product-video
Build product launch videos in Remotion from brief → storyboard → render → multi-agent review → iterate. Uses the social-clips repo infrastructure. Best when Austin provides a screen recording of the product as design inspiration and the launch brief/copy is available. Triggers on: product video, launch video, demo video, remotion video, make a video for launch.
Security Vetted
Reviewed by AI agents and approved by humans.
Skill Instructions
# Product Video Workflow
Build polished product launch videos using the `social-clips/` Remotion infrastructure. Proven on Sparkle V3 launch (2026-04-14).
## When to use
- Product launch needs a 15-30s social video
- New feature demo for X/LinkedIn
- Before/after product transformation clips
## Workflow
### 1. Gather inputs (parallel)
Launch in parallel:
- **Read the brief** — launch post, one-pager, landing page copy. Extract: headline, taglines, key features, tone direction.
- **Clone/check assets** — `social-clips/` for Remotion infra, product repo for brand tokens (fonts, colors, icons, logos).
- **Austin's screen recording** — ask for a 30-60s screen rec of the product in action. Use as DESIGN INSPIRATION only, never real content/file names.
- **Voice research** — if ghostwriting for Dan or another person, pull their recent posts for voice calibration.
### 2. Storyboard (before any code)
Write a shot list table:
| Beat | Time | Visual | Text overlay |
|------|------|--------|-------------|
Rules:
- **Use real product UI copy** — never invent labels, agent names, or features that don't exist in the actual app. Screenshot the real UI and mirror it.
- **Lead with the viewer's problem** (hook), not the product name.
- **Product must appear within 3 seconds** (a16z Speedrun research).
- **Before/after is the money shot** — design around it.
- **All text must be readable at 720p** (phone feed). Min 18px equivalent.
- **85% watch muted** — burn all captions in. No VO unless explicitly requested.
### 3. Build in Remotion
```bash
cd /Users/austintedesco/Documents/every-growth-os/social-clips
```
- Create `src/{project-name}/` with: `Scenes.tsx`, `theme.ts`, `fonts.tsx`, `mockData.ts`
- Register composition in `src/Root.tsx`
- Use `staticFile()` for assets in `public/{project-name}/`
- Standard output: 1920×1080, 30fps, h264 crf 18
**Font loading pattern** (prevents character clipping):
```tsx
const [handle] = useState(() => delayRender('fonts'));
useEffect(() => {
const font = new FontFace('Name', `url(${staticFile('fonts/file.otf')})`);
font.load().then(f => { document.fonts.add(f); continueRender(handle); });
}, [handle]);
```
**Crossfade transitions** — handle at orchestrator level, not per-scene. Per-scene exit fades fight the orchestrator.
### 4. Render-audit loop
```bash
# Single frame audit
npx remotion still <comp-id> out/test.png --frame 60
# Full render
npx remotion render <comp-id> out/video.mp4 --codec=h264 --crf=18
```
Render one frame per scene first. Fix layout/clipping issues before full render. Check:
- Text not clipped (line-height >= 1.2 for serif with descenders)
- Panels not stacking (AbsoluteFill defaults to flex-direction: column)
- Content not truncated in bubbles/cards
### 5. Multi-agent review (the step that catches everything)
After 2-3 self-iterations, render ~20 frames (peak + transition frames) to `out/review/` and spawn **4 agents in parallel**:
1. **Design/layout critic** — off-kilter elements, misalignment, proportions, cropping
2. **Text/readability critic** — legibility at 720p, contrast, truncation, typos
3. **Narrative/pacing critic** — story arc, attention peaks/drops, earned duration, CTA strength
4. **Brand consistency critic** — fonts, colors, UI chrome matching the real product
Each agent reads the PNG frames and returns a prioritized fix list. Compile all 4 + Austin's notes into a single revision plan.
### 6. Competitive research (optional but high-impact)
Spawn a research agent to pull:
- a16z Speedrun "How to Make a Viral Launch Video"
- Flowjam Product Hunt template
- Competitive video patterns (Arc, Linear, Cursor, CleanMyMac)
- Any relevant Lenny newsletter/podcast data
Apply top 3-5 actionable insights to the video.
### 7. Iterate on Austin's feedback
Austin reviews the video in QuickTime. Common feedback patterns:
- **"This text is cut off"** → line-height or overflow issue
- **"This feels clunky"** → animation timing too fast/slow, counter digit-flicker rate
- **"You invented this"** → replace with real product UI copy (screenshot the actual app)
- **"Hold longer"** → extend scene duration, keep animation timing same
- **"A little long"** → cut redundant scenes (narrative critic usually identifies which)
### 8. Ship
```bash
cp social-clips/out/<video>.mp4 ~/Desktop/<name>.mp4
```
Also deliver:
- Social copy pack (Dan voice: lowercase, no hype, concrete numbers, flat factual closer)
- Feature list for thread replies (pull from real email/launch copy, not your interpretation)
- Push to Proof doc for team review
## Key lessons (from Sparkle launch)
- **Never invent product UI labels.** Screenshot the real app and mirror the copy exactly.
- **Desktop resonates more than Downloads** for "messy Mac" narratives.
- **Counter animations**: match per-frame digit rate to the original feel when changing targets. Higher number ≠ same animation window.
- **Before/after stagger**: Before lands first (0.7-1s solo), then After crashes in with spring overshoot + yellow flash. Much more dramatic than simultaneous.
- **The chat/refine beat is the differentiator** — give it the most time. Show a command that's obviously useful and doesn't make the AI look dumb.
- **Endcard: one headline + CTA.** Don't stack 3 lines. Use the landing page's actual tagline, not something invented.
## Render commands
```bash
cd /Users/austintedesco/Documents/every-growth-os/social-clips
# Preview in browser
npm run studio
# Single frame
npx remotion still <id> out/frame.png --frame 60
# Full video
npx remotion render <id> out/video.mp4 --codec=h264 --crf=18
# GIF (for embeds)
ffmpeg -y -i out/video.mp4 \
-vf "fps=15,scale=960:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=128[p];[s1][p]paletteuse=dither=bayer:bayer_scale=3" \
out/video.gif
```