$npx -y skills add gooseworks-ai/goose-skills --skill render-mosaic-grid-revealRender a 'mosaic-grid-reveal' video from a config — a real-DOM FULL-BLEED N×N mosaic of real product tiles that pops in one tile at a time (scatter order, ease-out-back overshoot), the grid clears, then the brand wordmark builds line-by-line followed by a sub-label, tagline, and
| 1 | # render-mosaic-grid-reveal |
| 2 | |
| 3 | Render the `mosaic-grid-reveal` format from a config. The signature of this format is a |
| 4 | **full-bleed N×N mosaic** (default 3×3) of the brand's real product stills that **pops in |
| 5 | one tile at a time** (scatter order, ease-out-back "pop"), building the whole grid; the grid |
| 6 | then **clears** (scale-up + fade) and a clean end card **builds line-by-line** — the brand's |
| 7 | real wordmark, then a small sub-label, then the tagline, then a CTA. Silent by design (a |
| 8 | light music bed is muxed separately via `create-music-elevenlabs`). The hook is RANGE — nine |
| 9 | maximally-distinct variants show how much choice the brand offers. |
| 10 | |
| 11 | Everything is a real-DOM HTML scene **frame-stepped** to PNG via Playwright and encoded with |
| 12 | FFmpeg, so the wordmark, tile captions, and CTA stay **pixel-crisp** (a video model would |
| 13 | smear them). No generative video, no i2v, no AI-rendered text. This capability is **FREE and |
| 14 | deterministic** — the only paid step of the format (the music bed) is a separate media cap. |
| 15 | |
| 16 | ## Inputs (`config.json`) |
| 17 | |
| 18 | - `width`, `height`, `fps` — canvas + frame rate (default 1080×1920, 30). |
| 19 | - `wordmark` — brand logo SVG (full `<svg>` or bare `<path>` markup) or PNG path. Real DOM, |
| 20 | recolored via `palette.ink`. Never AI-render it. `wordmark_viewbox`, `wordmark_width` tune it. |
| 21 | - `palette` — `bg` (warm off-white), `accent` + `accent_deep` (brand color), `ink`, `cap`. |
| 22 | - `grid` — `cols`/`rows` (default 3×3), `inset` (outer margin), `gap`. |
| 23 | - `tiles` — one per cell (length must equal `cols*rows`): `image` (real variant still), |
| 24 | `name` (caption), `bg` (soft pastel echoing the variant), `ink` (deep caption color). |
| 25 | - `pop_order` — scatter order across cells (default corners → center → edges). |
| 26 | - `timing` — `grid_in0`, `cadence`, `pop`, `hold`, `clear` (seconds). |
| 27 | - `end_card` — `sub`, `tagline_top`, `tagline_bottom` (bold), `cta`, `url`. Brand's own approved copy only. |
| 28 | - `eyebrow` — optional top kicker held during the grid. |
| 29 | |
| 30 | `scripts/config.example.json` is a filled example (the Pair Eyewear "RANGE" worked example); |
| 31 | the tile `image`/`wordmark` paths are brand inputs bound by the orchestrator at remix time. |
| 32 | |
| 33 | ## Run |
| 34 | |
| 35 | ```bash |
| 36 | python3 scripts/build_html.py --config config.json --out hyperframe.html # emits scene, writes duration_sec back |
| 37 | python3 scripts/render.py --config config.json --html hyperframe.html --out master-silent.mp4 |
| 38 | ``` |
| 39 | |
| 40 | `build_html.py` computes the full timeline and writes `duration_sec` back into the config so |
| 41 | `render.py` (which reads dims/fps/duration from the config) frame-steps `window.renderAt(t)` |
| 42 | at `fps` and FFmpeg-encodes the silent master. Then mux the `create-music-elevenlabs` bed: |
| 43 | `ffmpeg -i master-silent.mp4 -i bed.wav -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -shortest out.mp4`. |
| 44 | |
| 45 | ## Rules |
| 46 | |
| 47 | - FILL the frame — tiles are full-bleed and edge-to-edge, NOT small cards floating in an |
| 48 | empty margin. Tiles pop in one at a time (scatter order), never all-at-once or static. |
| 49 | - Real wordmark + real product stills only. Never AI-render the logo or text. |
| 50 | - Copy slots are the brand's own approved lines — never invent claims, customers, results, |
| 51 | prices, or shipping speed. |
| 52 | - Pick the 9 most DISTINCT variants (color-wheel spread) — that IS the RANGE hook. |