Build a 6-second, Apple-style motion video announcing a Twitter/X handle change, rendered as a real MP4 using Remotion (React + TypeScript). Follow every spec below exactly — colors, frame numbers, easing configs — they are tuned values, not suggestions.
- DISPLAY_NAME: "Your Name" — your display name as it appears on X
- OLD_HANDLE: "your_old_handle" (without @)
- NEW_HANDLE: "your_new_handle" (without @)
- AVATAR: your profile photo (square) saved to
public/avatar.png
- Remotion 4 project:
remotion,@remotion/cli,@remotion/google-fonts, React 18, TypeScript. - One composition:
HandleReveal, 1920x1080, 60 fps, 360 frames (6.0s). - Font: Inter via
@remotion/google-fonts/Inter, weights 500/600/700/800, fallback-apple-system, 'Segoe UI', sans-serif. - Render:
npx remotion render src/index.ts HandleReveal out/handle-reveal.mp4 --codec h264 --crf 16. - Colors: ink
#0f1419, gray#536471, verified blue#1d9bf0, boil silver#9aa1ab.
- Background:
radial-gradient(115% 115% at 50% 40%, #ffffff 0%, #f2f4f6 55%, #e6e9ed 100%)(light theme, never dark). - Centered X profile hover-card: width 720, padding 44, border-radius 28, background #ffffff, border
1px solid #eef1f3, layered shadow0 48px 100px -24px rgba(15,20,25,0.32), 0 16px 40px rgba(15,20,25,0.10), 0 2px 8px rgba(15,20,25,0.05)— strong enough that the card separates from the background while the video plays. - Card contents (nothing else — no bio, no follower counts):
- Top row: circular avatar 124px (thin border
1px solid rgba(15,20,25,0.08)) top-left; official X logo SVG (24x24 path, ink color) at 30px top-right. - Name row (margin-top 26): DISPLAY_NAME at 48px Inter 800, letter-spacing -0.02em, ink color, with the official X verified-badge SVG (22x22 blue seal + white check path, fill #1d9bf0) at 40px, gap 12. The blue tick sits beside the name and is visible 100% of the time.
- Handle line (margin-top 8): 40px, line-height 1.35. Starts as
@OLD_HANDLEin gray weight 500, ends as@NEW_HANDLEin metallic silver weight 800.
- Top row: circular avatar 124px (thin border
- Gradient:
linear-gradient(180deg, #dfe2e7 0%, #b6bbc3 30%, #7d848f 55%, #99a0a9 75%, #bfc4ca 100%)withbackground-clip: text, transparent color. Smooth — deliberately NO hard white "horizon" stripe (it reads as a line through the letters) and NO text-shadow (it smudges). - Depth:
filter: drop-shadow(0 2px 3px rgba(15,20,25,0.3))on the silver text. - Weight 800 so it reads bold and solid, never washed out.
- Entrance (0–45): card fades in (opacity 0→1 over 18), rises 24px and scales 0.95→1 with
spring({damping: 200, durationInFrames: 45}). Contents stagger in (avatar delay 6, X logo 10, name 12, handle 16): each fades + rises 12px over 24 frames,Easing.out(Easing.cubic). - Zoom in (88): whole scene scales 1→1.7 with
spring({damping: 200, durationInFrames: 60}), transform-origin41% 60%(the handle area). The full card must stay inside the frame at peak zoom. - Matrix scramble (106): the handle decodes like a Matrix/decoder effect:
- The "@" never moves; it crossfades gray→silver over frames 106–126.
- Each character position i joins the "boil" at
106 + i*2: it cycles a new random glyph every 4 frames from charsetabcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ0123456789, drawn deterministically (Remotionrandom()seeded by position + step). Boiling glyphs: color #9aa1ab, weight 600, opacity 0.92, blur 0.5px, random vertical jitter ±1.5px per swap. - Fixed-width cells prevent wobble: each cell is an inline-block containing an invisible sizer glyph (the old character at weight 500 before its boil starts, the new character at weight 800 after) plus the visible boiling glyph absolutely positioned and centered over it.
- Old-handle characters beyond the new handle's length boil briefly then dissolve: opacity 0.9→0 starting
boilStart + 8over 9 frames, then unmount.
- Locks (134, one per 7 frames): new characters lock in one by one, left to right, at
134 + i*7. Each lock: the final silver glyph appears withspring({damping: 14, stiffness: 180, mass: 0.7})driving scale 1.16→1 (origin50% 70%), brightness 1.32→1, blur 0.8px→0. - Letter glint (184–230): a white light band travels across the finished handle: an overlaid copy of
@NEW_HANDLE(weight 800) withbackground-clip: text, gradientlinear-gradient(100deg, transparent 42%, rgba(255,255,255,0.95) 50%, transparent 58%), background-size260% 100%, background-position animated 100%→0% withEasing.inOut(Easing.cubic). - Zoom out (212): second spring (damping 200, 64 frames) subtracts 0.58 of scale — settles at 1.12x, a touch closer than the start.
- Card shine sweep (274–332): two skewed (-18deg) vertical bands sweep left→right across the card (inside an overflow-hidden, border-radius-inherit overlay;
leftgoes -70%→180%, eased inOut cubic): a 48%-wide soft slate tintrgba(148,163,184,0.22)plus, offset +11%, a 26%-wide white bandrgba(255,255,255,0.9)withmix-blend-mode: overlayso it glints over the avatar, name, tick, and silver letters. - Hold the final frame to 360.
Write a Node script (scripts/make-sfx.js) that synthesizes a 6.0s 48kHz stereo 16-bit WAV to public/sfx.wav, added to the composition with <Audio src={staticFile('sfx.wav')} />. Use seeded (deterministic) noise, an RBJ biquad bandpass with exponential frequency sweeps, raised-cosine envelopes, exponential-decay sine tones, and equal-power panning. Events (seconds):
- 0.08: soft air swell, noise 220→520 Hz, gain 0.05.
- 1.45: rising whoosh with the zoom-in, noise 260→1500 Hz over 1.05s, gain 0.13.
- 1.78: digital flutter under the boil, noise 2400→3200 Hz, gain 0.032, amplitude-modulated at 15 Hz (matches glyph swaps).
- Lock ticks at
(134 + i*7)/60for i = 0..6: sine tick at1250 * 2^(st/12)Hz with st = [0,2,4,7,9,11,14] (rising, musical), decay 0.045, gain 0.085 (last one 0.12), plus a low 290+i*24 Hz thock (gain 0.05) and a 4ms noise click (gain 0.06). - 176/60: gentle bell as the last letter lands — 1318.5 Hz + 2.76x harmonic at 0.28, decay 0.55, gain 0.07.
- 3.54: falling breath with the zoom-out, noise 1200→340 Hz, gain 0.08.
- 4.6: airy shimmer with the shine sweep, noise 3200→8200 Hz, gain 0.05, panned -0.75→+0.75.
- Normalize the final mix to 0.45 peak (cap makeup gain at 3x). Keep everything subtle — Apple-quiet, no loud effects.
- Before the final render, render PNG stills at frames ~118 (boil), ~150 (locks mid-zoom), ~205 (glint), ~278 (shine), 356 (end) with
npx remotion stilland inspect them: the silver must look bold and metallic (not washed out, no line through it), the whole card must be visible at peak zoom, the tick must sit beside the name in every frame. - Verify the MP4 has both streams with
npx remotion ffprobe: h264 1920x1080 60fps video + AAC 48kHz stereo audio. - Final output:
out/handle-reveal.mp4.
The finished video should read: calm white scene → card settles → camera pushes in → the handle boils like decoding text → letters lock into bold silver one by one with rising ticks → light passes over the letters → camera settles back → a shine sweeps the card → hold. Clean, minimal, professional.