Files
ai-agent/reel/README.md
Gabriel Vidal 07bd51cef7 chore(reel): web encode settings, end-card poster, drop unused deps
- render.mjs: CRF 26 with x264 aq-mode 3, which spends the bits on the dark
  gradients this mostly-ink film is made of — the same look as CRF 23 at
  ~30% less (31 MB at 1080p, 15 MB at 720p); the poster is the end card
  (logo, line, address, the bill) at 115 s
- the score is plain TypeScript DSP now, so Tone.js and playwright-core go
- README: how the score is actually made

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 06:19:08 +02:00

75 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The Tokunia reel
The 2-minute motion-design film on the [Tokunia landing page](../landing/)
(`landing/assets/tokunia-reel.mp4`). A [Remotion](https://www.remotion.dev)
project where **picture, score and sound effects share one beat grid**:
- `src/timeline.ts` — 128 BPM, 4/4, 64 bars = exactly 120 s; `at(bar, beat,
sixteenths)` → seconds; the nine chapters and their bars.
- `src/score.ts` — the drum grid, arrangement, fills, crashes, drops, risers,
notification pings and cron chimes, as data. The music renderer plays it; the
motion kit turns the same hits into envelopes (`hitEnv("kick", t)`), so a
pulse on screen lands on the sample it belongs to.
- `music/` — the original soundtrack, composed in code: plain TypeScript DSP
run in Node (D major, the 王道進行 progression, a hook over the three drops)
→ `public/audio/score.wav`; `music/check-music.mjs` re-measures it.
- `sfx/` — UI/system sounds from [効果音ラボ](https://soundeffect-lab.info/), the
library the Lost in Production trailer used. Free for commercial use but not
redistributable, so `sfx/fetch-sfx.sh` downloads them into `public/sfx/`
(gitignored).
- `src/scenes/<chapter>.tsx` + `<chapter>.cues.ts` — one scene per chapter and
its sound-effect cues (absolute seconds, pure data).
- `scripts/` — stills/contact sheets, the audio mix, the final render.
Nothing is filmed or screenshotted: the app's screens are redrawn as legible
components (`src/kit/ui.tsx`, `devices.tsx`) in its own dark theme, and Hemp
Henry — the app's avatar — is the mascot, stepping on eighth notes.
## Commands
```bash
npm run studio # Remotion Studio (scrub any chapter)
npm run stills -- ch-notifications 25:3 47.2 # stills at bar:beat or seconds + a contact sheet
npx remotion render ch-cron out/preview/cron.mp4 --scale=0.5 --concurrency=2 # quick motion check
npm run music # re-render the score
npm run sfx # fetch the sound effects
npm run render # picture + mix + mux → out/ (then landing/assets)
```
Compositions: `reel` (the film) and `ch-<chapter>` (one chapter with the same
backdrop, cuts, HUD and grain; frame 0 = its downbeat — `stills` converts
absolute seconds for you).
## Writing a chapter
- **Time is absolute seconds.** `const t = useT()` inside a scene returns film
time, not chapter time. Place everything with `at(bar, beat, sixteenths)`;
never hard-code frames.
- **Land on the music.** Entrances on beats, eighths for fast series, big moves
on downbeats and drops. Use `hitEnv("kick" | "clap" | "snare" | "hat" |
"openhat" | "tick" | "crash", t)` for pulses (scale 1 + 0.02 × kick, glow on
the clap). Nothing should sit perfectly still for more than a beat — keep a
slow push or drift under everything.
- **Open with `<ChapterTitle>`** on the chapter's first downbeat (index, title
with a full stop, accent, kicker). It holds ~3 beats, then collapses into a
tag in the top-left corner — keep that corner (≈ 520 × 130 px) free.
- **Leave the cut to the transition.** Every chapter boundary has a slab wipe
(`src/transitions.data.ts`) that fully covers the frame on the downbeat; give
your last half-beat an exit move (push, whip, scale-out) into it.
- **Readable at 1080p.** Hero words 140–260 px (Bricolage 800, `display()`),
statements 64–110 px, UI text ≥ 19 px, mono labels ≥ 18 px. Safe margins 96 px;
the bottom 120 px carries the HUD.
- **Palette.** Ink ground, cream paper, ember (cost), matcha (planet) + the
chapter accent. At most two accents on screen.
- **Sound.** List cues in `<chapter>.cues.ts` with the semantic names of
`src/kit/sfx.ts` (`tap`, `type`, `pop`, `notif`, `whoosh`, `register`, …);
`at` is where the transient lands. UI sounds sit under the music: gains
0.2–0.6, vary repeats with `rate`.
- **Kit first.** `src/kit/` has kinetic type (`Slam`, `Reveal`, `Typewriter`,
`Counter`, `Odometer`, `Scramble`, `Marquee`, `Mark`), effects (`Backdrop`,
`Flash`, `RingBurst`, `Sparks`, `Confetti`, `Shake`, `Camera`, `SpeedLines`),
the app (`Panel`, `Chip`, `ToolCard`, `Bubble`, `Composer`, `StatusChecks`,
`Kpi`, `Bar`, `Toggle`, `BottomNav`, `PageHead`, `HARNESS`, `MODEL`), devices
(`Phone`, `Browser`, `Laptop`), `Henry` and `Receipt`. `src/scenes/intro.tsx`
is the reference for how they combine.