Design System
System
Video · Engine

Video lab

Test-generate a Wallace video in TimDS’s local Video Lab: draft or load an answer, edit the beats, inspect the plan, render, and review the MP4 and cover in your browser. The lab uses this repository’s contract, registered media, and authored components in video/remotion.tsx. Remotion renders the frames headlessly; the lab itself is a separate web app.

Use the registered library. Footage and stills come from B-roll & footage and Thumbnails. Drafting produces a compile request; it does not generate new footage. TimDS owns the app, compiler, validation, staging, rendering, and packaging. Wallace owns the contract, catalog, and visual components.

Open the lab

Run npm run timds -- check to build the writing-brief index, then npm run video:lab. Open the local Video Lab and keep its server running. The video-lab launch configuration runs the same app from either the website or standalone Design System checkout.

  1. Load a saved input, paste a compile request, or describe a source for Draft. Draft uses the Anthropic credentials available to the server; the rest of the app works without them.
  2. Edit the exact question, topic, format, and answer beats. Check the plan to review scene timing, copy, footage chains, and cover selection.
  3. Save a deliberate fixture under video/lab/, then render. Review the MP4 and thumbnail in the app; they remain under ignored video-local/lab/<name>/out/.
CommandDoes
npm run video:labStarts TimDS’s web app on 127.0.0.1:4410
npm run video:lab -- --port 4500Uses another local port
npm run timds -- video lab <name> --planPrints scene timing, copy, footage chains, and cover without downloading media
npm run timds -- video lab <name> --prepareStages media and writes the generated entry without launching
npm run timds -- video lab <name> --renderRenders the video and cover headlessly
npm run video:studio -- <slug>Opens the separate Remotion Studio inspector for a ready production
npm run timds -- video lab --listLists inputs and ready productions
Lab inputs today: crash-footage-short, rear-end-crash-cam. Ready productions: driver-died-claim, insurer-not-responding, rear-end-collision, settlement-offer. Lab fixtures use silent word-share timing and carry no source authorization or publishing record. They are previews, not finished productions.

Drafting reads the exact-version dist/design-system/index.json. Rebuild with timds check after pulling a release or editing a writing-brief page. Credentials come from ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or an ant auth login profile; keep them out of launch files.

What the lab renders

Everything runs at 30fps. A lab input renders one format, the way the automated Video Lab ships one production per format; a ready five-record production renders the whole long-form-plus-short family.

From a lab input

CompositionOutputSizeComponent chain
TimDSVideoThe video, in the input’s outputFormat1920 × 1080 horizontal · 1080 × 1920 shortVideo → Scene → Media, CaptionPages, BrandWatermark; Intro and Outro on their cards
TimDSCoverThe cover still for that format3840 × 2160 horizontal · 1080 × 1920 shortHorizontalCover or VerticalCover → CoverVisual, GoldHeadline

From a ready production

Listed by the production slug in PascalCase; shorts are numbered in the order the production declares them.

CompositionOutputSizeComponent chain
<Slug>LongLong-form video1920 × 1080Video → Scene → Media, CaptionPages, BrandWatermark; Intro and Outro on their cards
<Slug>CoverLong-form cover still3840 × 2160HorizontalCover → CoverVisual, GoldHeadline
<Slug>Short1Vertical short1080 × 1920The same Video and Scene components with vertical set
<Slug>Short1CoverShort cover (frame zero)1080 × 1920VerticalCover → CoverVisual, GoldHeadline

Two kinds of footage, one Media component

A content scene declares one registered asset or an ordered chain in assets. Each entry plays at natural speed for its share of the scene under the same slow push-in; the kind of asset decides how it is drawn.

WorkflowAsset kindDrawn asScreen time
Crash Camvideo — a dashcam or security-camera clipMuted video at 1× speed, cut at the scene boundaryIts measured duration, never stretched
Character Storyimage — a character stillA held still with the same push-in, so it never reads as a freezeThe rest of the scene, or its share of a chain
Chain rules are shared code, not styling. video/footage.ts re-exports TimDS’s rules for the components and CI: consecutive picks must come from different footage families (offset, mirrored, and vertical derivatives are the same family; intro and outro cards break the sequence), a chain must cover the scene at natural speed, and the last clip holds at least two seconds by cutting the previous clip early. A scene that breaks a rule fails rendering and fails npm run check:video.

The component contract

The engine receives one map, wallaceVideoProjectComponents, exported at the end of video/remotion.tsx. Every entry starts as the TimDS default that was copied into the file; replace an entry to change that surface, and the engine keeps the rest. Props types are imported from @dtconcepts/timds/video/remotion, so a replacement is checked against the same contract the engine calls.

EntryPropsOwns
Videoproject, scenes, ids, pads, audioSrc, verticalSequences the scenes from the measured caption timings and plays each line’s voice take.
Sceneproject, scene, line, duration, lead, verticalOne content scene: footage, the eyebrow/headline/subline panel, watermark, and caption lane.
Introproject, question, verticalThe footage-free question card that opens a production.
Outroproject, verticalThe footage-free brand card: logo, site, tagline.
Coverproject, cover, verticalBoth cover stills unless a format-specific entry is set.
HorizontalCoverproject, coverThe 16:9 cover, composed on a 1280 × 720 grid and scaled to the export size.
VerticalCoverproject, cover, verticalThe 9:16 cover that becomes frame zero of every short.
Helpers stay helpers. Media, CaptionPages, BrandWatermark, CoverVisual, and GoldHeadline are exported for reuse inside a replacement but are not override points; a new Scene composes them rather than the engine.

Rules for a Wallace component

The same discipline as a marketing component, applied to a frame: consume the contract, never restate it.

  1. Brand comes from the contract. Colours, panel, fonts, logo, series, site, tagline, and watermark labels are read from project.contract.brand, which mirrors Brand. A literal colour or a second font family in a component is a defect; when the contract and Brand disagree, Brand wins and the contract is fixed.
  2. Copy is data, not layout. Eyebrow, headline, gold phrase, subline, and caption words arrive on the scene and caption records already validated against the word budgets (8 headline words horizontally, 8 in a short, 5 words per caption page). A component draws them; it never truncates, rewrites, or invents them. Wrap headlines with tieOrphan so no line ends on a single word, and highlight exactly one gold phrase.
  3. Footage plays at natural speed. Never slow, hold, loop, or freeze a clip to fill a scene. A chain that is too short is a production defect the render must surface, not a visual one to hide.
  4. Every frame carries brand and contact copy. Content scenes show the logo top-left. Horizontal frames keep both bottom labels and the Subscribe for more banner top-right. Vertical frames show Contact Wallace Pierce and wallacepierce.com under the logo, with the left watermark alone at the bottom. Intro and outro retain the banners. The vertical action rail stays clear.
  5. Text sits opposite the subject. Read the asset’s text and subject placement rather than centring copy over a face or an impact. The vertical scrim under full-bleed footage stays; 16:9 panels carry their own fill.
  6. Never draw a logo. The mark is always Img of brand.logo. A component that recreates, recolours, or reproportions it fails review.
  7. A frame is a pure function of the project and the frame number. No dates, randomness, network, or machine paths. The same records must render the same pixels on every machine and in CI.
  8. Stay inside the map. Edit video/remotion.tsx and video/footage.ts only. Do not add a second engine, a per-topic TSX file, a render script, or edits under ignored video-local/; do not run timds video components init again — --force discards every Wallace change and is only for an explicitly requested reset.

Gates

What runs on every change, locally and in CI. A rule that is not on this list is guidance, not a gate.

CommandChecks
npm run check:videoTimDS validates the contract, the producer block, the asset catalog, and every ready production; the footage-chain and headline-copy gates run over video/productions/; the component, footage, producer, strict fixture-finalization, and live lab-server tests run; video/remotion.tsx typechecks against the engine’s types.
npm run check:versionsReact and Remotion resolve to the single hoisted copy the engine uses. Two copies break React context at render time.
npm run check:mediaEvery asset a production can reference is published through TimDS.
npm run timds -- checkBuilds the viewer and machine index.
npm run check:video-labAfter the build, resolves the producer’s writing-brief blocks for both formats against the exact-version index; CI runs this without calling a model.
Drafts are not gated automatically. Pass a directory to run the copy and chain gates over a draft before restoring it: node --import tsx scripts/check-video-footage-chains.mjs video/drafts and node scripts/check-video-copy.mjs video/drafts.

Automated Video Lab

An outside lab compiles a reviewed answer into a Wallace production without knowing Wallace: the producer block in video/contract.json owns the role labels, the intro/engagement/outro structure, the CTA wording, and the asset-key vocabulary, and TimDS supplies the compiler and deterministic footage selection. The writing brief is assembled from the published Design System blocks the contract cites, so voice direction lives on these pages and nowhere in lab code. The local app uses this same compiler and client component module for its headless renders. When a local media file is missing or empty, TimDS downloads the published asset from the Design System cloud through media.json; a fresh workstation needs no copied media cache.

Beat roleEyebrow
hookWhat happened
ruleNorth Carolina law
riskWhat can go wrong
processWhat to do
exceptionThe exception
answerThe takeaway
engageWhat would you do? — a yes/no question the viewer can answer, horizontal only
outroThe fixed brand card
Engagement narration{{question}} Tell us what you would do in the comments.
Long-form outroIf this happened to you, contact Wallace Pierce at {{site}}. Subscribe for more about {{topic}}.
Short outroContact Wallace Pierce at {{site}}.
Cover eyebrowDashcam · North Carolina
Footage keysdash-*, cc-*, char-broll-*, character-broll-*, environment-broll-*, object-broll-* in video/assets.json
Cover keyscover-subject-* in video/assets.json
Brief blocksbrand/voice#four-rules brand/voice#words video/workflow#the-two-types video/workflow#production-rules video/b-roll#forbidden-in-every-clip video/b-roll#automated-selection
What the producer can ship today. Automated horizontal and Short videos can select from the complete published B-roll catalog, including dashcam, security-camera, character, environment, and object clips. TimDS matches the configured prefixes directly to the original asset keys. Every lab input is compiled and finalized in npm run check:video, and the producer and authoring tests check complete catalog coverage in both formats. The cover library the producer chooses from, cover-subject-, holds neutral scene stills, because a Crash Cam cover is a dashcam frame or a neutral scene and the producer selects images only; Character Story covers still resolve through Thumbnails by hand. Automated Shorts use published derivatives linked through each master’s vertical field; the live-crop fallback stays disabled. The crash-footage-short fixture keeps this render path checked alongside horizontal video.

Changing a component

  1. Branch design-system/<change>. Edit video/remotion.tsx; keep caption paging in video/footage.ts, shared footage rules in TimDS, and a component test in video/remotion.test.ts.
  2. Render both horizontal and short fixtures in the lab and inspect the first, middle, and last frame of every scene, then the cover. Check headline fit, caption lane, watermark, and subject collisions.
  3. npm run check:video, then npm run check, npm run timds -- check, and npm run check:video-lab.
  4. Record the change under ## Unreleased in CHANGELOG.md, update this page if a rule or gate changed, and submit with npm run timds -- submit.
  5. To adopt a newer TimDS default, diff node_modules/@dtconcepts/timds/video/remotion.tsx against the Wallace file and port the change by hand. The generator never overwrites it.

Owner: Wallace Pierce Design System