| name | create-motion-graphics-remotion |
| description | render motion graphics from an approved storyboard manifest using a remotion (react) project. produces crisp deterministic text and timeline-precise motion. use for kinetic typography, snappy logo reveals, animated infographics, and any motion graphic where text quality and timing matter more than photoreal video. |
create-motion-graphics-remotion
Purpose
Render motion graphics from an approved storyboard.html/manifest.json (produced by create-motion-graphics-storyboard) using Remotion. Remotion is React-based programmatic video: text is real DOM, timing is deterministic frame math, and animation primitives map cleanly onto Spring + interpolate. This avoids the text-hallucination and timing-drift failure modes of pure video-gen models.
The atom can scaffold a fresh Remotion project on first run or reuse an existing one in the run folder. It generates one Scene component per storyboard scene, wires them into a root composition with <Series>, and renders to clips/scene-NN.mp4 (per-scene) plus optionally a stitched master.
Inputs
- A storyboard manifest (
scenes array with id, start, end, copy, elements: [{kind, primitive, easing, ...}], music_cue) and optional sharedLayers array describing elements that persist across scene boundaries (see storyboard atom for schema).
- A brand-board manifest (palette + Google Fonts + aesthetic direction).
- Output directory (the run folder). The Remotion project lives at
<run>/remotion/.
- Optional
--scene <id> to re-render only one scene.
- Optional
--fps (default 30) and aspect ratio (default 9:16, 1080x1920).
Workflow
- Read the storyboard and brand-board manifests.
- If
<run>/remotion/ does not exist, run scripts/init-remotion-project.sh <run>/remotion to bootstrap the project (npm i remotion @remotion/cli @remotion/google-fonts @remotion/bundler plus dev deps).
- Generate
src/Root.tsx exporting a <Composition> with id MotionGraphic, width/height/fps from inputs. The composition body is an <AbsoluteFill> containing a <Series> of scene components AND, on top, a <SharedLayers> overlay component that interpolates each shared layer's properties across global time using the storyboard's sharedLayers keyframes. The shared overlay reads useCurrentFrame() at the composition level so a single circle can smoothly translate from scene 1 → scene 2.
- For each storyboard scene, render
references/scene-template.tsx into src/scenes/Scene{NN}.tsx, parameterized with the scene's elements array. The template uses useCurrentFrame, spring, and interpolate to implement each supported primitive — see references/remotion-primitives.md. Multi-element scenes compose elements inside one <AbsoluteFill>, each with its own primitive and absolute or flex layout per the storyboard.
- Load brand fonts via
@remotion/google-fonts named imports based on the brand-board manifest.
- For each scene (or the single
--scene), run scripts/render-composition.sh <run>/remotion <scene-id> <out-path> which wraps npx remotion render with H.264 defaults.
- Optionally render the full composition to
<run>/clips/master-silent.mp4.
- Write
manifest.json listing every rendered clip, the Remotion project path, and font/composition settings. Write verification.md.
Output
<run>/remotion/ — the Remotion project (reusable across re-rolls).
<run>/clips/scene-NN.mp4 — silent per-scene renders.
- Optional
<run>/clips/master-silent.mp4 — stitched silent master.
manifest.json and verification.md.
Quality Checks
- Every scene listed in the storyboard has a corresponding rendered clip.
- Clip dimensions and duration match the storyboard (within one frame).
- On-screen text matches storyboard copy exactly (no truncation, no font fallback).
- No raster glyphs — text is real DOM rendered by Remotion.
- All Google Fonts loaded successfully (no system-font fallback).
- Safe-area at animation peak. For every
scale-bounce/pop-in scene, sample the spring peak (~frame 12–18 at 30fps with the default config — overshoot is ~1.15x for damping: 12). Confirm no text glyph crosses outside the 88% safe area. Springs overshoot; sizing for the static frame is wrong.
- Safe-area at scene mid-frame. For every scene, sample the mid-frame and confirm no text or critical element exits the 88% safe area.
- Every scene container in the generated TSX sets
maxWidth: "88%" on the text element (or equivalent padding) so overshoots clip safely rather than pushing offscreen.
Failure Modes
- Node or npm not available — surface and mark blocked; do not silently skip.
- Remotion install fails — surface the npm error.
- Storyboard scene uses a primitive not implemented in
scene-template.tsx — extend the template or fall back to the nearest primitive and surface the substitution.
- Font fails to load — fall back to the nearest brand-board font and flag in the manifest.
- Render times out — re-run only the affected scene with
--scene <id>.
- Text clips the canvas at the spring peak. Symptom: scene looks fine at frame 0 and frame 30 but text overshoots horizontally around frame 12–18. Fix: reduce the scene's font-size by 15–20% (or set
maxWidth: "82%" on the text element) and re-render only that scene.