Render a 'photo-grid promo card' video from a config — a real-DOM card with a FIXED header/footer and a CONTINUOUSLY SCROLLING 2-row grid of MIXED tiles (video clips, product/lifestyle stills, big-serif %-OFF, dark promo-code or CTA) + feature chips, frame-stepped via Playwright with real-time <video> playback and encoded with FFmpeg — deterministic assembly, FREE (the clips + music come from create-video-fal + create-music-elevenlabs), text stays pixel-crisp. Use for the photo-grid-promo-card format.
npx gooseworks install --all # then, in Claude Code, Cursor, or Codex: /gooseworks use the render-photo-grid-card skill
Render the 'photo-grid promo card' format from a config. The signature of this format is a
continuously scrolling 2-row grid (NOT a static card) under a fixed header (brand
wordmark + big headline + sub) and fixed feature chips. The grid-viewport scrolls left
across the whole ~10s, edge-faded with a CSS mask, and its tiles are mixed media:
video clips playing inside tiles, band-product/photo stills, big-serif pct/off
type tiles, and a dark code (promo code) or cta tile.
The renderer itself is FREE/deterministic (Playwright frame-step + FFmpeg). The paid inputs
are separate capabilities: the tile clips come from create-video-fal (i2v of the
product heroes, or clips extracted from the brand's own ad corpus) and the music from
create-music-elevenlabs. Text (wordmark, %, code) is real DOM — never AI-rendered.
build_card.py --config config.json --out hyperframe.html ; render.py --config config.json --html hyperframe.html --out master-silent.mp4 — 1080x1920, scrolling grid, deterministic, $0.
Clip tiles are driven by FRAME-SWAP, not <video>: render.py pre-extracts each clip to
PNG frames with ffmpeg, preloads them, and swaps each <img class="vidframe">'s src per
output frame. This is because Playwright's bundled Chromium can't decode <video> H.264
over file:// (open-source build, no proprietary codecs) — it hangs on canplay. Letting
ffmpeg decode makes it codec-independent AND deterministic. Provide clips longer than the
master (or the swap just loops them); a subtle setpts-slow reads as cinematic.
cols), NOT total tiles; the grid fills row-major.palette is a brand fact — pass the brand kit's colors; build_card.py only falls back to neutral
greys. The occasion copy, clip moments and music feel are the recipe's user choices, never defaulted.cols), NOT total tiles; the grid fills row-major.palette is a brand fact — pass the brand kit's colors; build_card.py only falls back to neutralFull video production sequence with script review, actual ingredient choices, controlled generation, editing, evidence-based quality review, polish, captions and delivery. A host binding supplies project storage, authentic approvals, provider access and billing.
Build a vox-pop street interview video ad. An interviewer with a handheld mic asks passers-by one question about the brand's product, they give blunt wrong guesses, one gives the real answer, and the cut lands on a branded end card. Generates the takes through the GooseWorks fal proxy (Seedance 2.0 with native voice), then grades, re-cuts, captions and gates them locally. Use for the street-interview format.
Write the words of a short-form video ad (voiceover, dialogue, chat bubbles, on-screen lines) the way performance creative teams do instead of from a blank page. Builds the script from the buyers' own words, the beat sheet of an ad that already works and three deliberately different angles, filters them with a rule check and a second non-Claude model, and takes the strongest into the review with the other two as one-line swaps. Use it in every video ad run before any paid step, and whenever the user asks to write, rewrite or improve a video ad script or says a script sounds generic or AI-written.