Remotion Video Builder
Build complete Remotion video compositions from style guides. This skill bridges the gap between a visual style specification, hand-authored or reverse-engineered from a reference video, and a working, renderable Remotion composition with new content.
Prerequisites
Before starting, verify:
- Remotion project exists: either an existing project, or create one:
npx create-video@latest my-video
cd my-video
npm install
- Style guide available: a STYLE-GUIDE.md covering canvas dimensions, colors, fonts, text animation, cut rhythm, and audio specs. Write it by hand, or derive it from a reference video.
- For voiceover: an ElevenLabs API key in
ELEVENLABS_API_KEY, or an equivalent TTS service
- For transcription: a Gemini API key in
GEMINI_API_KEY for word-level timestamps, or whisper.cpp installed locally
- For B-roll: a Pexels API key in
PEXELS_API_KEY for automated fetching, or manual asset collection
Key setup: export the keys your workflow actually needs before starting, for example export ELEVENLABS_API_KEY="..." in your shell profile or a project .env file. Only the voiceover step needs ElevenLabs, only the transcription step needs Gemini, and only automated B-roll needs Pexels, so a manual-asset run may need no keys at all.
Workflow
Step 1: Load & Parse Style Guide
Read the STYLE-GUIDE.md and extract every parameter into a mental model:
Canvas parameters:
- Width, height, FPS, typical duration
- Safe zones (top, bottom, left, right padding)
Visual parameters:
- Background color (canvas)
- Color palette (primary text, accent colors, color rules)
- Font family, weight, case, letter spacing, line height
- Text sizes (hook vs. main captions)
- Text positioning (vertical %, horizontal alignment, max width)
- Caption styling (pill background vs. bare text, shadows, outlines)
Animation parameters:
- Text animation type: karaoke word-reveal, pop-in, typewriter, phrase-swap
- Animation timing: instant reveal, fade duration, scale curves
- Sentence boundary behavior: hard-cut, fade-out, slide-up
Layout parameters:
- Layout modes (floating card, full-bleed, split-screen, etc.)
- Layout distribution (% of video in each mode)
- Image treatment: Ken Burns zoom, padding, corners, shadows
Audio parameters:
- Voice specs (voice name, stability, similarity, speed, model)
- Music bed volume relative to voice
- SFX inventory (cuts, transitions, reveals)
- Audio format requirements
Editorial parameters:
- Storytelling template / beat structure
- Typical word count and WPM
- Vernacular rules (sentence length, pronouns, TTS quirks)
- CTA style
Action: Read the style guide. Summarize the extracted parameters back to the user for confirmation before proceeding. Flag any gaps that need filling.
Step 2: Write the Script
The script drives everything: timing, assets, duration. Write it before anything else.
- Select a storytelling template from the style guide, or load
references/storytelling-templates.md for options
- Ask the user for the topic/story: what is this video about?
- Draft the script following:
- The beat structure from the chosen template
- Word count and WPM targets from the style guide
- TTS optimization rules (see below)
- The style guide's vernacular rules (pronoun ratios, sentence length, tone)
- Present the script with beat labels and estimated timing per section
- Get user approval before proceeding. The script is the contract.
TTS Writing Rules (apply to all scripts):
- No rhetorical questions unless the style guide explicitly uses them. TTS reads questions with an unnatural rising intonation
- Short sentences (8-15 words) produce better prosody than long ones
- Use concrete nouns over abstract concepts. TTS handles them better
- Spell out numbers for natural reading ("eight hundred" not "800")
- Use em dashes (written
-- in these templates) for punchy pauses, periods for full stops
- ALL CAPS on words that need stress emphasis
- Avoid parenthetical asides. TTS does not handle nested clauses well
- End sentences on strong nouns, not prepositions or weak verbs
Step 3: Generate Voiceover
- Match voice to style guide specs: use the exact voice name, model, and settings specified
- If using ElevenLabs MCP tools: use
mcp__elevenlabs__text_to_speech with:
- Voice ID from style guide (or search with
mcp__elevenlabs__search_voices)
- Model ID (e.g.,
eleven_multilingual_v2)
- Stability, similarity, style, speed settings from style guide
- If using ElevenLabs API directly: format the script following the ElevenLabs formatting guide (em dashes for pauses, ALL CAPS for emphasis, phoneme tags for mispronunciations)
- Save audio to the project's
public/ directory (e.g., public/voiceover.mp3)
- Get the audio duration:
ffprobe -v error -show_entries format=duration -of csv=p=0 public/voiceover.mp3
Checkpoint: Play the audio back or confirm with user before proceeding to transcription.
Step 4: Transcribe with Word-Level Timestamps
Word-level timestamps are the backbone of caption sync and scene timing.
Option A: Gemini API (preferred for accuracy)
- Upload the audio file to Gemini with a prompt requesting word-level timestamps
- Parse the response into the standard format
Option B: whisper.cpp (local, no API needed)
./whisper.cpp/main -m models/ggml-medium.en.bin -f public/voiceover.mp3 --output-json --max-len 1 --word-timestamps true
Output format, saved as public/captions.json:
[
{ "word": "this", "start": 0.4 },
{ "word": "company", "start": 0.72 },
{ "word": "changed", "start": 1.14 },
{ "word": "everything", "start": 1.52 }
]
Post-processing:
- Verify first and last word timestamps align with audible speech start/end
- Calculate total duration: last word start + ~0.5s buffer
- Calculate total frames:
Math.ceil(audioDurationSeconds * fps)
- Group words into sentences/phrases based on punctuation and pause gaps (>500ms = sentence break)
Step 5: Collect Assets
Based on the script, identify and collect visual assets.
- Create an asset list: for each sentence or scene in the script, describe the ideal B-roll image or clip:
Scene 1 (0:00-0:03): "Company X changed logistics forever" → warehouse/logistics footage
Scene 2 (0:03-0:07): "They started with a simple idea" → founder portrait or early office
- Source assets:
- Pexels API: If the project has a
fetch-broll.ts script, use it. Otherwise, use the Pexels API directly with search terms from the asset list. Request portrait orientation (9:16) and minimum 1080px width.
- Manual collection: Ask the user to provide specific images/clips
- Web search: For brand-specific assets (logos, product shots), search and download
- Save to project:
public/broll/broll-01-description.jpg (or .mp4 for video clips)
- Create a manifest if the project pattern uses one:
[
{ "file": "broll-01-warehouse.jpg", "description": "Warehouse logistics", "source": "pexels", "id": "12345" },
{ "file": "broll-02-founder.jpg", "description": "Company founder", "source": "manual" }
]
Asset quality checklist:
- Minimum 1080px wide (for 1080x1920 canvas)
- No watermarks
- Appropriate aspect ratio (portrait preferred, landscape can be cropped)
- Visual variety: a mix of close-ups, wide shots, abstract, concrete
Step 6: Build Remotion Components
IMPORTANT: Before creating any components, read the existing project structure thoroughly. Follow existing patterns for file organization, naming conventions, imports, and prop types.
Load references/component-patterns.md for reusable component templates.
6a. Canvas / Theme Setup
Create or update the theme/token file based on the style guide:
// theme.ts or tokens.ts
export const theme = {
canvas: { width: 1080, height: 1920 },
colors: {
background: '#FFFFFF',
primaryText: '#000000',
accent: '#FFD700', // from style guide
},
fonts: {
primary: { family: 'Inter', weight: '900' },
},
text: {
hookSize: 110,
captionSize: 75,
case: 'lowercase' as const,
letterSpacing: '-0.02em',
lineHeight: 1.2,
maxWidth: 0.8, // fraction of canvas width
verticalPosition: 0.72, // fraction of canvas height
},
safeZones: {
top: 120, bottom: 270, left: 40, right: 40,
},
};
6b. Load Fonts
// fonts.ts
import { loadFont } from '@remotion/fonts';
export const fontFamily = loadFont({
family: 'Inter',
url: 'https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuBWYAZ9hiA.woff2',
weight: '900',
}).fontFamily;
6c. Build Components Based on Style Guide
Select and build components matching the style guide's layout modes and animation types. Common patterns (see references/component-patterns.md for full implementations):
| Component |
Use When Style Guide Specifies |
| FloatingCard |
Images on colored/white canvas with padding, optional Ken Burns |
| KaraokeCaption |
Word-by-word reveal synced to timestamps |
| PhraseCaptions |
Phrase-based captions (dark pill or bare text) |
| HardCutSequencer |
Scene manager for asset switching at frame boundaries |
| MusicBed |
Looped background audio at configurable volume |
| HookScene |
Colored background + hero asset + large text for opening |
| SplitLayout |
Multiple images or top/bottom split on canvas |
Component rules:
- One component per file, under 200 lines
- All timing derived from audio timestamps and FPS, never hard-coded frame numbers
- Use
useCurrentFrame() and useVideoConfig() from Remotion
- Use
interpolate() and spring() for all animations
- Props should be typed with Zod schemas when the project uses them
6d. Register the Composition
In Root.tsx (or wherever compositions are registered):
import { Composition } from 'remotion';
export const Root: React.FC = () => {
return (
<Composition
id="new-video-name"
component={MainComposition}
durationInFrames={totalFrames} // from audio duration * fps
fps={30}
width={1080}
height={1920}
defaultProps={clipConfig}
/>
);
};
Step 7: Configure Scene Sequence
Map every script sentence to a scene with precise timing.
const clips = [
{
file: 'broll/broll-01-warehouse.jpg',
startFrame: 0,
endFrame: 90, // 3 seconds at 30fps
layout: 'floating-card',
words: [
{ word: 'this', start: 0.4 },
{ word: 'company', start: 0.72 },
{ word: 'changed', start: 1.14 },
{ word: 'everything', start: 1.52 },
],
},
{
file: 'broll/broll-02-founder.jpg',
startFrame: 90,
endFrame: 210, // next 4 seconds
layout: 'floating-card',
words: [ /* ... */ ],
},
// ... one entry per scene
];
Scene timing rules:
- Each scene boundary should align with a sentence break in the voiceover
- Scene duration should match the style guide's cut rhythm (e.g., 2-4s for fast cuts, 4-6s for split-screen)
- The first scene is the hook, so use the hook-specific styling from the style guide
- The last scene may need special treatment (CTA overlay, end card, etc.)
Frame number calculation:
startFrame = Math.round(firstWordTimestamp * fps)
endFrame = Math.round(lastWordTimestamp * fps) + paddingFrames
Step 8: Preview & Iterate
- Start the preview server:
npx remotion preview
- Visual checks against style guide:
- Use Playwright MCP for automated screenshot comparison if available:
- Navigate to
http://localhost:3000 and take screenshots at key frames
- Compare against style guide reference screenshots
- Fix discrepancies in a tight build-check-fix loop
- If recreating from a reference video (not just a written style guide), use the graded recreation loop instead of eyeballing:
- Work one scene at a time: recreate, gate, then advance. Whole-video passes do not converge.
- Build a contact sheet per scene (grid collage of source frames, start → end) so you can "read" the motion arc as one image; feed it plus source frames alongside the style guide.
- Render frames at timestamps matching the source (
npx remotion still), Read them side-by-side with the ground-truth source frames, and grade the match /10 (layout fidelity, animation smoothness). Iterate until ≥9 before moving to the next scene.
- Watch for the two known failure modes: missed layering (image behind text) and animation overlap at scene boundaries.
- Render final video:
npx remotion render MainComposition out/video.mp4
Component Architecture Patterns
These are the core reusable patterns for Remotion video styles. Full implementations with TypeScript code are in references/component-patterns.md.
1. Floating Card
Image centered on canvas with configurable padding. Optional Ken Burns zoom (scale interpolation over scene duration). Sharp or rounded corners. Drop shadow optional. Used for documentary-style B-roll presentation on clean backgrounds.
2. Karaoke Caption
Word-by-word reveal synced to audio timestamps. Each word transitions from invisible to visible at its exact timestamp. Words accumulate to form phrases, then hard-cut on sentence boundaries. Config: font, size, weight, case, color, position, maxWidth, shadow.
3. Hard Cut Sequencer
Scene manager that maps an array of scene configs (with startFrame/endFrame) to Remotion <Sequence> components. Only the active scene renders at any given frame. Handles scene transitions (hard cut only, no dissolves unless the style guide specifies otherwise).
4. Music Bed
<Audio> component with loop enabled and configurable volume. Typically set to 0.05-0.1 (about -20dB relative to voice). Starts at frame 0, runs full duration. Can include fade-in/fade-out at composition boundaries.
5. Split Layout
Canvas divided into regions (top/bottom, left/right, grid). Each region renders a different asset or component. Used for talking-head + B-roll splits, multi-image showcases, before/after comparisons.
6. Hook Scene
The opening 2-4 seconds. Colored or branded background with a hero asset (scaled, centered) and large text overlay. May include entrance animation (zoom-in, scale-up). Sets the visual tone for the entire video.
Key Rules
- Read the existing project structure first, then follow its patterns for file organization, naming, imports, and prop typing. Never impose a foreign architecture.
- Never hard-code timing: all frame numbers must be derived from
audioTimestamp * fps. If the voiceover is re-recorded, the video should re-sync automatically.
- One component per file, under 200 lines. Split large components into focused sub-components.
- The style guide is the source of truth: every visual decision (color, font, position, animation) must reference a specific value from it. If the style guide does not specify something, ask the user.
- Test audio sync at boundaries: check the first word and last word of every scene. If they are off by more than 2 frames, adjust.
- Use the project's existing theme system: if the project has
theme.ts, design tokens, or a shared config, extend it rather than creating a parallel system.
- Check the Remotion docs for API questions (animations, sequencing, fonts, audio). https://www.remotion.dev/docs is authoritative; a Remotion API reference skill, if you have one installed, is a faster lookup.
- Assets go in
public/. Never import assets from src/. Remotion serves from public/ via staticFile().
- Reference-driven beats prompt-driven for complex motion. Do not try to describe intricate animation in prose. Give a reference video or image, a contact sheet, or a start image plus an end image (generate the end state if needed) and let the agent reason from those. Attach an "art of the possible" reference too, such as an existing Remotion project full of complex animation or the official Remotion examples, so the model knows what the library can actually do.
Quick Reference: File Outputs
At the end of the workflow, the project should contain:
project/
src/
Root.tsx # Updated with new composition registration
components/
[VideoName].tsx # Main orchestrator component
[AssetLayer].tsx # B-roll / image rendering
[CaptionLayer].tsx # Text animation component
[HookScene].tsx # Opening scene (if style uses one)
theme.ts # Design tokens from style guide
fonts.ts # Font loader
public/
voiceover.mp3 # Generated TTS audio
captions.json # Word-level timestamps
broll/
broll-01-*.jpg # B-roll assets
broll-02-*.jpg
...
sfx/
music.mp3 # Background music (if style uses one)
Troubleshooting
| Problem |
Solution |
| Captions out of sync |
Check that captions.json timestamps are in seconds (not ms). Verify FPS matches between transcription assumption and composition config. |
| Font not rendering |
Ensure font is loaded via @remotion/fonts or @remotion/google-fonts. Check that fontFamily is passed to the text component's style. |
| Audio not playing in preview |
Use staticFile('voiceover.mp3') not a relative path. Ensure file is in public/. |
| Ken Burns jittery |
Use interpolate() with Easing.inOut(Easing.ease), not spring, for slow zoom. |
| White flash between scenes |
Ensure scene endFrame equals next scene startFrame (no gap). Use the sequencer pattern. |
| Video too long/short |
Recalculate durationInFrames from actual audio duration: Math.ceil(duration * fps). |
1---2name: remotion-video-builder3description: Build a complete Remotion video composition from a written style guide. Takes a STYLE-GUIDE.md describing canvas, colors, fonts, text animation, cut rhythm, and audio, then produces a renderable composition with new content. Covers script writing, voiceover generation, word-level caption sync, asset collection, and component architecture. Use when asked to "build a video in this style," "create a new reel," "make a video like [reference]," "produce a Remotion video," or any request to create a programmatic video from a style template. Works with any Remotion project and does not assume a particular folder layout.4---56# Remotion Video Builder78Build complete Remotion video compositions from style guides. This skill bridges the gap between a visual style specification, hand-authored or reverse-engineered from a reference video, and a working, renderable Remotion composition with new content.910---1112## Prerequisites1314Before starting, verify:15161. **Remotion project exists**: either an existing project, or create one:17 ```bash18 npx create-video@latest my-video19 cd my-video20 npm install21 ```222. **Style guide available**: a STYLE-GUIDE.md covering canvas dimensions, colors, fonts, text animation, cut rhythm, and audio specs. Write it by hand, or derive it from a reference video.233. **For voiceover**: an ElevenLabs API key in `ELEVENLABS_API_KEY`, or an equivalent TTS service244. **For transcription**: a Gemini API key in `GEMINI_API_KEY` for word-level timestamps, or whisper.cpp installed locally255. **For B-roll**: a Pexels API key in `PEXELS_API_KEY` for automated fetching, or manual asset collection2627> **Key setup**: export the keys your workflow actually needs before starting, for example `export ELEVENLABS_API_KEY="..."` in your shell profile or a project `.env` file. Only the voiceover step needs ElevenLabs, only the transcription step needs Gemini, and only automated B-roll needs Pexels, so a manual-asset run may need no keys at all.2829---3031## Workflow3233### Step 1: Load & Parse Style Guide3435Read the STYLE-GUIDE.md and extract every parameter into a mental model:3637**Canvas parameters:**38- Width, height, FPS, typical duration39- Safe zones (top, bottom, left, right padding)4041**Visual parameters:**42- Background color (canvas)43- Color palette (primary text, accent colors, color rules)44- Font family, weight, case, letter spacing, line height45- Text sizes (hook vs. main captions)46- Text positioning (vertical %, horizontal alignment, max width)47- Caption styling (pill background vs. bare text, shadows, outlines)4849**Animation parameters:**50- Text animation type: karaoke word-reveal, pop-in, typewriter, phrase-swap51- Animation timing: instant reveal, fade duration, scale curves52- Sentence boundary behavior: hard-cut, fade-out, slide-up5354**Layout parameters:**55- Layout modes (floating card, full-bleed, split-screen, etc.)56- Layout distribution (% of video in each mode)57- Image treatment: Ken Burns zoom, padding, corners, shadows5859**Audio parameters:**60- Voice specs (voice name, stability, similarity, speed, model)61- Music bed volume relative to voice62- SFX inventory (cuts, transitions, reveals)63- Audio format requirements6465**Editorial parameters:**66- Storytelling template / beat structure67- Typical word count and WPM68- Vernacular rules (sentence length, pronouns, TTS quirks)69- CTA style7071> **Action**: Read the style guide. Summarize the extracted parameters back to the user for confirmation before proceeding. Flag any gaps that need filling.7273---7475### Step 2: Write the Script7677The script drives everything: timing, assets, duration. Write it before anything else.78791. **Select a storytelling template** from the style guide, or load `references/storytelling-templates.md` for options802. **Ask the user for the topic/story**: what is this video about?813. **Draft the script** following:82 - The beat structure from the chosen template83 - Word count and WPM targets from the style guide84 - TTS optimization rules (see below)85 - The style guide's vernacular rules (pronoun ratios, sentence length, tone)864. **Present the script** with beat labels and estimated timing per section875. **Get user approval** before proceeding. The script is the contract.8889**TTS Writing Rules (apply to all scripts):**90- No rhetorical questions unless the style guide explicitly uses them. TTS reads questions with an unnatural rising intonation91- Short sentences (8-15 words) produce better prosody than long ones92- Use concrete nouns over abstract concepts. TTS handles them better93- Spell out numbers for natural reading ("eight hundred" not "800")94- Use em dashes (written `--` in these templates) for punchy pauses, periods for full stops95- ALL CAPS on words that need stress emphasis96- Avoid parenthetical asides. TTS does not handle nested clauses well97- End sentences on strong nouns, not prepositions or weak verbs9899---100101### Step 3: Generate Voiceover1021031. **Match voice to style guide specs**: use the exact voice name, model, and settings specified1042. **If using ElevenLabs MCP tools**: use `mcp__elevenlabs__text_to_speech` with:105 - Voice ID from style guide (or search with `mcp__elevenlabs__search_voices`)106 - Model ID (e.g., `eleven_multilingual_v2`)107 - Stability, similarity, style, speed settings from style guide1083. **If using ElevenLabs API directly**: format the script following the ElevenLabs formatting guide (em dashes for pauses, ALL CAPS for emphasis, phoneme tags for mispronunciations)1094. **Save audio** to the project's `public/` directory (e.g., `public/voiceover.mp3`)1105. **Get the audio duration**:111 ```bash112 ffprobe -v error -show_entries format=duration -of csv=p=0 public/voiceover.mp3113 ```114115> **Checkpoint**: Play the audio back or confirm with user before proceeding to transcription.116117---118119### Step 4: Transcribe with Word-Level Timestamps120121Word-level timestamps are the backbone of caption sync and scene timing.122123**Option A: Gemini API (preferred for accuracy)**124- Upload the audio file to Gemini with a prompt requesting word-level timestamps125- Parse the response into the standard format126127**Option B: whisper.cpp (local, no API needed)**128```bash129./whisper.cpp/main -m models/ggml-medium.en.bin -f public/voiceover.mp3 --output-json --max-len 1 --word-timestamps true130```131132**Output format**, saved as `public/captions.json`:133```json134[135 { "word": "this", "start": 0.4 },136 { "word": "company", "start": 0.72 },137 { "word": "changed", "start": 1.14 },138 { "word": "everything", "start": 1.52 }139]140```141142**Post-processing:**143- Verify first and last word timestamps align with audible speech start/end144- Calculate total duration: last word start + ~0.5s buffer145- Calculate total frames: `Math.ceil(audioDurationSeconds * fps)`146- Group words into sentences/phrases based on punctuation and pause gaps (>500ms = sentence break)147148---149150### Step 5: Collect Assets151152Based on the script, identify and collect visual assets.1531541. **Create an asset list**: for each sentence or scene in the script, describe the ideal B-roll image or clip:155 ```156 Scene 1 (0:00-0:03): "Company X changed logistics forever" → warehouse/logistics footage157 Scene 2 (0:03-0:07): "They started with a simple idea" → founder portrait or early office158 ```1592. **Source assets**:160 - **Pexels API**: If the project has a `fetch-broll.ts` script, use it. Otherwise, use the Pexels API directly with search terms from the asset list. Request portrait orientation (9:16) and minimum 1080px width.161 - **Manual collection**: Ask the user to provide specific images/clips162 - **Web search**: For brand-specific assets (logos, product shots), search and download1633. **Save to project**: `public/broll/broll-01-description.jpg` (or `.mp4` for video clips)1644. **Create a manifest** if the project pattern uses one:165 ```json166 [167 { "file": "broll-01-warehouse.jpg", "description": "Warehouse logistics", "source": "pexels", "id": "12345" },168 { "file": "broll-02-founder.jpg", "description": "Company founder", "source": "manual" }169 ]170 ```171172**Asset quality checklist:**173- Minimum 1080px wide (for 1080x1920 canvas)174- No watermarks175- Appropriate aspect ratio (portrait preferred, landscape can be cropped)176- Visual variety: a mix of close-ups, wide shots, abstract, concrete177178---179180### Step 6: Build Remotion Components181182**IMPORTANT**: Before creating any components, read the existing project structure thoroughly. Follow existing patterns for file organization, naming conventions, imports, and prop types.183184Load `references/component-patterns.md` for reusable component templates.185186#### 6a. Canvas / Theme Setup187188Create or update the theme/token file based on the style guide:189190```typescript191// theme.ts or tokens.ts192export const theme = {193 canvas: { width: 1080, height: 1920 },194 colors: {195 background: '#FFFFFF',196 primaryText: '#000000',197 accent: '#FFD700', // from style guide198 },199 fonts: {200 primary: { family: 'Inter', weight: '900' },201 },202 text: {203 hookSize: 110,204 captionSize: 75,205 case: 'lowercase' as const,206 letterSpacing: '-0.02em',207 lineHeight: 1.2,208 maxWidth: 0.8, // fraction of canvas width209 verticalPosition: 0.72, // fraction of canvas height210 },211 safeZones: {212 top: 120, bottom: 270, left: 40, right: 40,213 },214};215```216217#### 6b. Load Fonts218219```typescript220// fonts.ts221import { loadFont } from '@remotion/fonts';222223export const fontFamily = loadFont({224 family: 'Inter',225 url: 'https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuBWYAZ9hiA.woff2',226 weight: '900',227}).fontFamily;228```229230#### 6c. Build Components Based on Style Guide231232Select and build components matching the style guide's layout modes and animation types. Common patterns (see `references/component-patterns.md` for full implementations):233234| Component | Use When Style Guide Specifies |235|-----------|-------------------------------|236| **FloatingCard** | Images on colored/white canvas with padding, optional Ken Burns |237| **KaraokeCaption** | Word-by-word reveal synced to timestamps |238| **PhraseCaptions** | Phrase-based captions (dark pill or bare text) |239| **HardCutSequencer** | Scene manager for asset switching at frame boundaries |240| **MusicBed** | Looped background audio at configurable volume |241| **HookScene** | Colored background + hero asset + large text for opening |242| **SplitLayout** | Multiple images or top/bottom split on canvas |243244**Component rules:**245- One component per file, under 200 lines246- All timing derived from audio timestamps and FPS, never hard-coded frame numbers247- Use `useCurrentFrame()` and `useVideoConfig()` from Remotion248- Use `interpolate()` and `spring()` for all animations249- Props should be typed with Zod schemas when the project uses them250251#### 6d. Register the Composition252253In `Root.tsx` (or wherever compositions are registered):254255```typescript256import { Composition } from 'remotion';257258export const Root: React.FC = () => {259 return (260 <Composition261 id="new-video-name"262 component={MainComposition}263 durationInFrames={totalFrames} // from audio duration * fps264 fps={30}265 width={1080}266 height={1920}267 defaultProps={clipConfig}268 />269 );270};271```272273---274275### Step 7: Configure Scene Sequence276277Map every script sentence to a scene with precise timing.278279```typescript280const clips = [281 {282 file: 'broll/broll-01-warehouse.jpg',283 startFrame: 0,284 endFrame: 90, // 3 seconds at 30fps285 layout: 'floating-card',286 words: [287 { word: 'this', start: 0.4 },288 { word: 'company', start: 0.72 },289 { word: 'changed', start: 1.14 },290 { word: 'everything', start: 1.52 },291 ],292 },293 {294 file: 'broll/broll-02-founder.jpg',295 startFrame: 90,296 endFrame: 210, // next 4 seconds297 layout: 'floating-card',298 words: [ /* ... */ ],299 },300 // ... one entry per scene301];302```303304**Scene timing rules:**305- Each scene boundary should align with a sentence break in the voiceover306- Scene duration should match the style guide's cut rhythm (e.g., 2-4s for fast cuts, 4-6s for split-screen)307- The first scene is the hook, so use the hook-specific styling from the style guide308- The last scene may need special treatment (CTA overlay, end card, etc.)309310**Frame number calculation:**311```312startFrame = Math.round(firstWordTimestamp * fps)313endFrame = Math.round(lastWordTimestamp * fps) + paddingFrames314```315316---317318### Step 8: Preview & Iterate3193201. **Start the preview server**:321 ```bash322 npx remotion preview323 ```3242. **Visual checks against style guide:**325 - [ ] Canvas dimensions and background color match326 - [ ] Font family, weight, size, and case match327 - [ ] Text position (vertical %) matches328 - [ ] Caption animation type matches (karaoke vs. phrase-swap vs. pop-in)329 - [ ] First word of each scene syncs with audio330 - [ ] Last word of each scene syncs before cut331 - [ ] Asset layout matches (floating card padding, Ken Burns zoom range)332 - [ ] Cut rhythm feels right (not too fast, not too slow)333 - [ ] Music bed volume is subordinate to voice334 - [ ] Safe zones respected (no text behind platform chrome)3353. **Use Playwright MCP** for automated screenshot comparison if available:336 - Navigate to `http://localhost:3000` and take screenshots at key frames337 - Compare against style guide reference screenshots3384. **Fix discrepancies** in a tight build-check-fix loop3395. **If recreating from a reference video** (not just a written style guide), use the **graded recreation loop** instead of eyeballing:340 - Work **one scene at a time**: recreate, gate, then advance. Whole-video passes do not converge.341 - Build a **contact sheet** per scene (grid collage of source frames, start → end) so you can "read" the motion arc as one image; feed it plus source frames alongside the style guide.342 - Render frames at timestamps matching the source (`npx remotion still`), Read them side-by-side with the ground-truth source frames, and grade the match /10 (layout fidelity, animation smoothness). Iterate until ≥9 before moving to the next scene.343 - Watch for the two known failure modes: missed **layering** (image behind text) and **animation overlap at scene boundaries**.3446. **Render final video**:345 ```bash346 npx remotion render MainComposition out/video.mp4347 ```348349---350351## Component Architecture Patterns352353These are the core reusable patterns for Remotion video styles. Full implementations with TypeScript code are in `references/component-patterns.md`.354355### 1. Floating Card356Image centered on canvas with configurable padding. Optional Ken Burns zoom (scale interpolation over scene duration). Sharp or rounded corners. Drop shadow optional. Used for documentary-style B-roll presentation on clean backgrounds.357358### 2. Karaoke Caption359Word-by-word reveal synced to audio timestamps. Each word transitions from invisible to visible at its exact timestamp. Words accumulate to form phrases, then hard-cut on sentence boundaries. Config: font, size, weight, case, color, position, maxWidth, shadow.360361### 3. Hard Cut Sequencer362Scene manager that maps an array of scene configs (with startFrame/endFrame) to Remotion `<Sequence>` components. Only the active scene renders at any given frame. Handles scene transitions (hard cut only, no dissolves unless the style guide specifies otherwise).363364### 4. Music Bed365`<Audio>` component with loop enabled and configurable volume. Typically set to 0.05-0.1 (about -20dB relative to voice). Starts at frame 0, runs full duration. Can include fade-in/fade-out at composition boundaries.366367### 5. Split Layout368Canvas divided into regions (top/bottom, left/right, grid). Each region renders a different asset or component. Used for talking-head + B-roll splits, multi-image showcases, before/after comparisons.369370### 6. Hook Scene371The opening 2-4 seconds. Colored or branded background with a hero asset (scaled, centered) and large text overlay. May include entrance animation (zoom-in, scale-up). Sets the visual tone for the entire video.372373---374375## Key Rules3763771. **Read the existing project structure first**, then follow its patterns for file organization, naming, imports, and prop typing. Never impose a foreign architecture.3782. **Never hard-code timing**: all frame numbers must be derived from `audioTimestamp * fps`. If the voiceover is re-recorded, the video should re-sync automatically.3793. **One component per file, under 200 lines.** Split large components into focused sub-components.3804. **The style guide is the source of truth**: every visual decision (color, font, position, animation) must reference a specific value from it. If the style guide does not specify something, ask the user.3815. **Test audio sync at boundaries**: check the first word and last word of every scene. If they are off by more than 2 frames, adjust.3826. **Use the project's existing theme system**: if the project has `theme.ts`, design tokens, or a shared config, extend it rather than creating a parallel system.3837. **Check the Remotion docs for API questions** (animations, sequencing, fonts, audio). <https://www.remotion.dev/docs> is authoritative; a Remotion API reference skill, if you have one installed, is a faster lookup.3848. **Assets go in `public/`.** Never import assets from `src/`. Remotion serves from `public/` via `staticFile()`.3859. **Reference-driven beats prompt-driven for complex motion.** Do not try to describe intricate animation in prose. Give a reference video or image, a contact sheet, or a start image plus an end image (generate the end state if needed) and let the agent reason from those. Attach an "art of the possible" reference too, such as an existing Remotion project full of complex animation or the official Remotion examples, so the model knows what the library can actually do.386387---388389## Quick Reference: File Outputs390391At the end of the workflow, the project should contain:392393```394project/395 src/396 Root.tsx # Updated with new composition registration397 components/398 [VideoName].tsx # Main orchestrator component399 [AssetLayer].tsx # B-roll / image rendering400 [CaptionLayer].tsx # Text animation component401 [HookScene].tsx # Opening scene (if style uses one)402 theme.ts # Design tokens from style guide403 fonts.ts # Font loader404 public/405 voiceover.mp3 # Generated TTS audio406 captions.json # Word-level timestamps407 broll/408 broll-01-*.jpg # B-roll assets409 broll-02-*.jpg410 ...411 sfx/412 music.mp3 # Background music (if style uses one)413```414415---416417## Troubleshooting418419| Problem | Solution |420|---------|----------|421| Captions out of sync | Check that `captions.json` timestamps are in seconds (not ms). Verify FPS matches between transcription assumption and composition config. |422| Font not rendering | Ensure font is loaded via `@remotion/fonts` or `@remotion/google-fonts`. Check that `fontFamily` is passed to the text component's style. |423| Audio not playing in preview | Use `staticFile('voiceover.mp3')` not a relative path. Ensure file is in `public/`. |424| Ken Burns jittery | Use `interpolate()` with `Easing.inOut(Easing.ease)`, not spring, for slow zoom. |425| White flash between scenes | Ensure scene endFrame equals next scene startFrame (no gap). Use the sequencer pattern. |426| Video too long/short | Recalculate `durationInFrames` from actual audio duration: `Math.ceil(duration * fps)`. |