--- name: animated-video description: "Timeline-based motion design" user-invocable: true --- # Animated video Create an animated video or motion design piece rendered as an HTML page. Build a timeline-based animation with smooth transitions. Design frame-by-frame sequences with playback controls (play/pause, scrubber). Focus on visual storytelling with the Anthropic brand palette. Export-ready at a fixed aspect ratio (16:9 or 9:16). If you need to know the position of an element (eg to move a cursor or character between elements) use refs to grab the position. ALWAYS build on the `animations_v3.jsx` starter for ANY animation piece — including one hosted on a design-components page (the helmet-script + x-import structure IS the starter case, not an exemption). The only exemptions: a minor animated accent inside a larger non-animation design, or the user explicitly asking you not to use the starter. Skipping the starter silently removes the user's timeline editor — scene trims, speed changes, and video export only exist when the page builds on the engine. Do NOT load `animations.jsx` or `animations-v2.jsx` alongside it (the engines share window globals — last wins). A project that already uses an older starter keeps it; don't migrate existing animations. START by calling `copy_starter_component` with `kind: "animations_v3.jsx"` — the continuous-composition engine: the whole animation is ONE element tree rendered from one authored-time clock, so elements move, morph, and persist across section boundaries by ordinary interpolation — nothing mounts or unmounts at a boundary. It gives you ``, `useComposition()` (→ {T, CUES}), ``, ``, an `Easing` library, and `interpolate()` / `animate()` tweens. Read the file after copying. THE AUTHORING CONTRACT (it's in the file's usage block; follow it exactly): declare the scene list as a JSON string literal in a plain inline `` (exact JSON.stringify formatting, no spaces) — NOT in a text/babel script and NOT in a sibling .jsx (only vanilla inline script literals are addressable for the editor's write-back); declare `window.OM_PLAYBACK` the same way; pass both through untouched as `` wrapping ONE component — the whole piece. The scene list is the user-control view (names, order, playback durations); the engine derives the cue table from it, so the literal is the single source of structure. The user edits timing on the host timeline — trim a scene's edge, or set a section's speed — and every edit writes back into your literal and reflows the composition live. CUE-FIRST DISCIPLINE (this is what makes a piece read as one continuous video): 1. Write the OM_SCENES literal FIRST — it is the piece's outline. Get {T, CUES} from `useComposition()` and key ALL choreography to T and CUES.SectionName (authored seconds) — never to your own clock, never to wall-clock time. 2. One helper component per section for readability, but ALL of them render ALL the time inside the one tree, keyed to cues — never conditionally mounted per section. A shared element crossing a boundary is just motion whose start and end straddle a cue. 3. Define exactly three motion helpers up front (e.g. `MOTION = {enter, draw, pop}` wrapping Easing curves) and use no easing or transform outside them; one caption element, one visible at a time (`` has this built in). TIMING IS USER-EDITABLE (time-stretch): when the user trims or speeds a section, the engine replays that section's SAME authored slice over the new playback length — choreography keyed to T retimes, never cuts off. Authored hard cuts are content now, not structure: wrap a shot's elements in `` (visibility flips at the cues; children stay mounted so images and videos hold their readiness). A looping piece shows its last authored frame immediately before its first — make them match. Give every motion project a tweaks panel (`kind: "tweaks_panel.jsx"`) whose TWEAK_DEFAULTS include `"motionEditor": true` with a `` wired to it. That key is the host timeline editor's visibility gate: the user flips it in the Tweaks panel to hide or show the editor bar, and the animation, its timing data, and export are untouched either way. Declare the TWEAK_DEFAULTS literal in a plain inline `