paste this link into your ai. it will know what to do.
Build a SaaS product launch video the way Cursor, Notion, Linear and Higgsfield build theirs — from the real product, in Remotion, cut to a music bar grid, with every UI surface rebuilt as a component (never a cropped screenshot) and every number coming from real data. Use when someone asks for a launch video, product film, feature reveal, promo, or "make a video like the Cursor/Higgsfield ones" for a web app they have the code for. Covers reference study, footage and data sourcing, the Remotion kit, scene grammar, the stem-based score, the anti-slop rules, QA by contact sheet, and the founder
launch-film
A method, a component kit and a set of hard rules for making a launch video that looks like it came from a top product studio, using Claude Code + Remotion + ffmpeg. It was distilled from seventeen reviewed cuts of one real launch film. The rules below are the ones that survived review.
Read this file fully before starting. Then read references/grammar.md and references/anti-slop.md. Everything else is loaded on demand.
What you will produce
out/<name>-vN.mp4— 1920×1080, 60 fps, H.264 CRF 17, audio two-pass loudnormed to −14 LUFS / −1 dBTP.- A Remotion project (
templates/remotionis the starter) whoseFilm.tsxis a timeline on a music bar grid. - A score arranged from separated stems that follows the scenes (
scripts/stemscore2.py). - Contact sheets in
qa/proving every beat before you show it. - A
README.mdlog: one section per version, what changed and why. Versions are never overwritten.
The workflow
Work in this order. Each phase has a gate. Do not skip the gate because the phase "looks done".
Phase 0 — Study the references (30–45 min, do it every time)
Download 4–6 launch films the user admires (yt-dlp works for x.com). Make dense frame sheets (scripts/frame_sheet.sh <mp4> <fps>) and read them frame by frame. Write down, per film: cut count, average shot length, the grammar devices used, how UI is framed, how text appears, how colour changes between beats, how the music is cut. references/grammar.md holds the findings from Cursor Router, Cursor Automate, Notion AI and two Higgsfield films; add yours.
Gate: you can name the five devices you will borrow and the three you will not.
Phase 1 — Source real material (never placeholders)
Order of preference, all of them real:
- The codebase. Build demo routes with fixture data (
app/demo/*), record them with Playwright (light and dark), and export 2× stills. Measure event times in the mp4 by frame difference, never trust the script's timestamps. - The database, internal accounts only. Saved ads, generated assets, product images, real briefs. Join on the internal-users table so no customer data is used. Download to
public/real/, trim videos to ≤7 s at 540×960, downscale stills to ≤1400 px. - The brand deck. Crop the mark, read the palette and type, copy the taglines verbatim.
- Rebuild the UI as React components from the design tokens (
references/real-data.md). Screenshots are allowed only as full windows in a tour; never crop an element out of one.
Gate: every pixel on screen is either the product, real data from the product, or type. If you catch yourself drawing a "generated result" in CSS, stop and go get a real one.
Phase 2 — Lock the grid, then the story
Pick the music first (Phase 4 has the how), detect its BPM, and define B(k) = k × bar. Every scene starts on a bar. Every click lands on a downbeat. The one big moment (the "drop") is the ANCHOR. Write the story as a list of bars:
B0 brand stamp (dark) B14 the click (drop)
B2 statement (light) B16 next chapter (colour flip)
B4 the ask (composer types) ...
B8 the answer (chat canvas) B28 closer (dark) + creditTwo or three chapters, each 2 bars, is the rhythm that worked. Nothing static for more than ~1.5 s. Light/dark/colour alternate between chapters so no two consecutive scenes share a look.
Gate: read the bar list aloud as a story. If a bar is "show the dashboard", it has no story and gets cut or captioned into one.
Phase 3 — Build in Remotion with the kit
templates/remotion/src/kit/ has the primitives that survived review:
| primitive | use |
|---|---|
Rise, WordReveal, StreamText | the only entrances: fade + 12–24 px rise, 70 ms stagger; text streams at 60–70 cps |
Composer, Bubble | the product's composer and user message, rebuilt |
Card, Row, Spark, Bars, LineChart | answer cards with live micro-visuals; lines draw with strokeDashoffset |
Cursor2 | keyframed cursor: arrive → pause ≥ 0.6 s → click dip 15 %/80 ms → the page reacts → camera follows |
ProcessButton | Apply → "Applying" spinner (0.65 s) → check draws → status line → toast. A state swap is never a cut |
OrangeBurst | a disc grows out of the button you just clicked into a full-colour frame, types one line, wipes up |
Wall | a masonry of real videos pouring in (stagger 4 f, blur→sharp), spotlight on one |
Tour | full windows, one per beat, camera settles + 4 % push-in, label + one-line caption |
OpenDark, CloseDark | brand bookends: mark, wordmark typing with echo outlines, mono taglines, tiny credit |
Flow2 | node → mark → cycling node, lines draw, arrow always lands with a gap |
Camera is one scale() on an AbsoluteFill with a moving transformOrigin: lean 1.04–1.10 toward what matters next, never tilt, never 3D. Scroll is a single translateY on a tall canvas.
Gate: npx tsc --noEmit clean; half-scale draft render; contact sheet of every beat (scripts/contact_sheet.py) read by you before anyone else sees it.
Phase 4 — Score that plays as one piece
references/music.md has the full method. Short version: generate 30 s takes (MusicGen) or take a licensed track, separate stems with Demucs, then scripts/stemscore2.py loops whole bars and arranges bass/drums/other per scene with static per-scene gain, bar-quantized changes, long ramps (0.8–1.0 s), one suck-out → hit at the ANCHOR, at most two soft accents elsewhere. Six level states in a minute is plenty; more and it "isn't one piece". Time-stretch the stems to the grid BPM at 1 ms accuracy rather than moving your grid.
Gate: listen. If you can hear where the arrangement changes, smooth it.
Phase 5 — QA, deliver, log
- Full render → two-pass
loudnorm(scripts/loudnorm2pass.sh) → verify −14 ± 0.5 LUFS. - Contact sheets of the moments that changed since last version. Look for: cursor off the button, element cut by a crop, text arriving after the scene it belongs to, anything static.
- Name the file
<Project>_Launch-Video-vN.mp4. Never overwrite a previous version. - Append a README section: the feedback quoted, what changed, the grid, the score settings.
Gate: the last frame you looked at is the last frame of the film.
Hard rules
- No placeholders. No gradient tiles with fake brand names, no CSS "generated result", no lorem.
- No cropped elements. A crop that cuts through a border looks like a beginner's edit. Rebuild the component.
- No slides. A headline beside a UI card, a colour column with a claim, three stills in a row — all read as PowerPoint. Content must move as one continuous canvas or the camera must move.
- Reading time. Dwell ≥ 0.6 s + 0.3 s per word, then move. But nothing static longer than ~1.5 s.
- Clicks are choreography. Arrive, pause, dip, page reacts, then the camera follows. Every click on a downbeat.
- State changes are processes. Loading → progress → result. Show the product's real loading UI.
- Transitions are motivated. The next scene grows out of the thing you just touched.
- Every loader resolves. If two tiles start spinning, two tiles land.
- Numbers are real and consistent. The question, the sentence and the chart must agree.
- Brand is the deck's, not yours. Upright wordmark if the deck is upright; their taglines, their mono voice.
- One shadow tier per surface. No glow, burst, glitch, dither, shake, speed lines, tilted windows.
- A tiny credit in the closer if the maker wants one — 15 px, visible before the fade.
The review loop
Show every version. Log what changed per version in the README. Treat vague review notes as precise diagnoses: "looks generated" means a placeholder or a generic loading state; "feels like slides" means a static composition; "looks pasted" means a state swap instead of a process; "the music doesn't feel like one piece" means too many level changes. Never re-litigate a rejected device; remove it and find a better one.
Files
references/grammar.md— reference-film grammar, device by devicereferences/anti-slop.md— the visual rules with the exact numbersreferences/music.md— MusicGen → Demucs → stemscore, BPM matching, loudnormreferences/real-data.md— how to get real footage, data and assets safelyscripts/—stemscore2.py,musicgen.py,frame_sheet.sh,contact_sheet.py,loudnorm2pass.sh,tempo.pytemplates/remotion/— the Remotion starter with the kit and an example Film
keep it where your ai can reach it.
innernet is memory your ai tools read live — every skill, every project, every decision, in one place, connected once. save this skill to yours, or publish one of your own as a link like this.