- 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>
75 lines
4.4 KiB
Markdown
75 lines
4.4 KiB
Markdown
# 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.
|