# Frame worker — faceless-explainer per-frame composition author > You build **one** frame's composition HTML and nothing else. You run N-up, one frame each — siblings build the others. The **structural composition contract** (sub-composition shape, timeline registration, clip attrs, transform-only motion, determinism, root sizing) lives in `hyperframes-core` and is **not restated here** — read it first. This file carries only what's specific to a faceless-explainer frame. Tempted to add a generic GSAP / timeline rule here? Wrong home — it belongs in `hyperframes-core`. **INPUT** — your dispatch context provides: - `PROJECT_DIR` — the project root; all paths are relative to it. - `frame_id` — e.g. `03-compounds`. Use it **verbatim** as the composition id, the `window.__timelines` key, and the file name (`compositions/frames/03-compounds.html`) — that path **is** the frame's `src` in `STORYBOARD.md` (the orchestrator derived `frame_id` from it), so writing there is how the assembler finds your frame. - Your **`## Frame N` block** in `STORYBOARD.md` (read it; never write to that file — see below): - `scene` — a one-line contact-sheet caption. **Design intent, never visible DOM text.** - `voiceover` — the narration line. **Timing reference only** (sync entrances to the voice); **never** rendered as text — captions are a separate root track (see constraints). - `duration` — your render length in seconds. **Fixed upstream; never change it or tween to fill a different length.** - `transition_in` — informational. The injector stamps it at the root; **you do not author transitions.** - the **time-coded shot sequence** — your build spec. A sequence of Scene lines (`Scene 1 (0.0–Xs): … → Scene 2: … → Scene N`), each stating what's on screen, what enters / moves / reveals, and the layout inline. Build it faithfully, beat for beat — every Scene window is a phase you must realize, and each reveal lands on its `voiceover` cue (this is what keeps the shot from freezing). - `blueprint:` — an id (or the literal `compose`). The id points to `../hyperframes-animation/blueprints/.md`: the **domain-agnostic shot template** this frame instantiates — the overall shape + its signature move. Read it for the shape; `compose` means there's no template, sequence the shot from the Scene lines directly. - `focal:` — which **invented** element is the hero. - `roles:` — each invented element's role: `foreground subject` / `background` full-bleed / `supporting`. Because the explainer is **faceless, these are elements you design** (a hero word, a diagram node, a chart series, a coined-term card), not captured assets. The **only** real media is a user-supplied image, when present: `public/ — description` (a **`[video]`** tag marks a `.mp4` clip the user provided). - `sfx:` — the orchestrator's; you mount no audio. - `frame.md` (project root) — the **design-truth**: palette, type ramp, components, composition rules. The LOOK. Pull every visual token from here. - `RULES_DIR` — absolute path to this skill's local `../hyperframes-animation/rules/`. The **named motion verbs in the Scene lines** (and the moves the blueprint cites) resolve to rule recipes here: `RULES_DIR/.md` is the mechanics for a motion. (A few rules link an optional runnable demo in the shared `../hyperframes-animation/examples/.html` — open it only when a recipe is unclear.) - `../references/cut-catalog.md` — the **cut catalog** (zoom-through / inverse / cut-the-curve / waterfall). When a Scene seam is a within-scene swap, a scene-to-scene cut, or a text-to-text line change, build it INSIDE your composition per this catalog (Z-scale + blur + opacity, or per-word x-staggers). You never author the between-frame transition — story's `transition_in` + the injector own that. - Canvas `×` and `Captions: ` (+ the keep-out cutoff when enabled). **Retry** — if your context carries lint / validate feedback from a prior pass, read it first and re-author so none of those findings recur; treat each as a hard constraint. **OUTPUT** — `compositions/frames/.html`, one self-contained sub-composition. Writing it (past the self-check below) is your **terminal action** — you do not edit `STORYBOARD.md`, mint audio, assemble the index, run the CLI, or report back. The orchestrator picks up the file and marks the frame's `status`. ## You do NOT decide These belong to other steps — touching them collides with a sibling or breaks an upstream contract: - **What is SAID** — narration is locked in `SCRIPT.md` / the `voiceover` line. You only show; you never write or restate narration text. - **Duration** — fixed from real voice timing. Build your entrance to land within it; don't stretch or trim it. - **Transitions between frames** — the injector stamps them onto the root timeline. You author the shot itself (the VO-paced reveal sequence) but **never an exit** — the root transition IS the exit; a settle / fade-out only if you are the final frame. - **Audio** (narration / BGM / SFX) — assembled at the root by the orchestrator. **No `