$npx -y skills add gooseworks-ai/goose-skills --skill render-value-propRender a designed 'value prop' video from a config — 3-5 noun-phrase benefit claims (<=4 words each) revealed sequentially over per-SKU product visuals, one crisp editorial frame per claim (hook sticker -> N claim beats -> brand end card). Deterministic PIL/HTML beat renderer fra
| 1 | # render-value-prop |
| 2 | |
| 3 | Render a designed 'value prop' video from a config: a hook sticker, then one beat per short noun-phrase benefit claim (<=4 words each — "Drug-Free", "Zero Sugar", "NSF Certified"), each pairing the claim headline with a per-SKU product visual (the hero SKU rotates beat to beat so the eye anchor shifts), then a brand-wordmark end card. Text + product carry the spot — no narration, no talking head — and it is built to be legible sound-off. Every beat is a pure function of beat-local time `t` (deterministic PIL start frames + Playwright hyperframes + FFmpeg); no CSS keyframes, no setTimeout. FREE (no paid calls); music is a separate capability (create-music-elevenlabs), or ship silent for $0. |
| 4 | |
| 5 | ## Run |
| 6 | `render_master.py --config config.json --project <dir>` -> `<dir>/finals/master-clean.mp4` (silent), |
| 7 | 1080x1920, deterministic, $0. The renderer is **fully config-driven** — palette, copy, SKUs, |
| 8 | pacing, hook, logo and end card all come from `config.json` (schema = `ad_sample.recipe.config`; |
| 9 | see `config.example.json`). Nothing is hardcoded to one brand. `build_storyboard_preview.py` is an |
| 10 | optional free preview gallery for the gate; `build_text_overlays.py` is optional (transparent |
| 11 | text-zone PNGs for compositing claims over a motion clip). |
| 12 | |
| 13 | Environment: run with a **Python that has Playwright** (override the frame-render interpreter with |
| 14 | `RENDER_PYTHON`); `ffmpeg` is auto-discovered (`FFMPEG` env > PATH > common prefixes). The frame |
| 15 | renderer `render_hyperframe.py` is **bundled** in `scripts/` — no external atom to fetch. |
| 16 | |
| 17 | ## Contract |
| 18 | - Deterministic + FREE (Playwright frame-step + FFmpeg); no paid calls, no AI-rendered text. |
| 19 | - Claims are noun phrases, <=4 words; never <3, never >5. Optional benefit sentence <=12 words. |
| 20 | - One product visual per beat; rotate which SKU is the hero. Never reuse a flat variety-pack image as every canvas. |
| 21 | - Sound-off legibility is the bar: the headline uses the config `palette.ink` color on `palette.bg`; |
| 22 | the per-beat **accent** color (from `value_props[].accent` — a SKU-accent slug or a hex) is the |
| 23 | accent rule, not the headline. |
| 24 | - Product widths **auto-scale from each image's aspect ratio** (target display height), so tall |
| 25 | sachet cutouts and wide product packshots both frame correctly. |
| 26 | - Assets are packshots, not always transparent cutouts: set `palette.bg` to the product image's |
| 27 | background color for seamless compositing (free — avoids a paid background-removal step). |
| 28 | - Uniform pacing (hook ~3.0s, props 2.0-2.5s each, endcard ~2.0s); total lands in the 10-20s window (~17s). No acceleration curve. |
| 29 | - No human face is the focus. End card uses the brand wordmark **image** when a hi-res one |
| 30 | (aspect >= ~1.2, i.e. a real >=1200x600 wordmark) is provided via `config.logo`; otherwise it |
| 31 | **falls back to a typographic `brand_name` wordmark** (many brands ship only a favicon). |
| 32 | - Music is added separately by create-music-elevenlabs (quiet instrumental bed at -14 dB), or ship silent. |