storebound/media/teaser
CRT 930f960318 teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes
Portfolio (every app, both stores, rollout %, crash sparklines), the Growth and
Health charts with a real hover sweep (one captured frame per hovered day, the
pointer follows the recorded positions), the Prices matrix (both stores per
country, gaps marked), then v5's release timeline and 0 blockers. All frames are
real fixture-mode captures (desktop.ts). Tests: scenes 4-5 s, 50-60 s total,
captions >= 3 s, every desktop frame captured by desktop.ts and present.
2026-10-12 02:32:53 +08:00
..
icons teaser v4: calm 60 s 16:9 cut, from an empty folder to ready on both stores 2026-10-12 01:48:03 +08:00
desktop.ts teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00
index.html teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00
music.js teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00
poster.jpg Teaser: Phosphor cursor and icons, a desktop app scene, new render for the site 2026-10-11 10:59:32 +08:00
README.md teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00
render.ts teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00
script.js teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00
site-shots.ts flows, listing translate, scan 2.2 + --originality, prices export with subscriptions, site sections 2026-10-12 01:24:21 +08:00
teaser.js teaser v6: 55.5 s, v5 kept, its desktop part grown to four scenes 2026-10-12 02:32:53 +08:00

storebound teaser (55.5 s, 16:9)

A calm, scripted motion piece: from an empty folder to everything ready on both stores. Every frame is a pure function of time, rendered from an HTML/CSS/JS timeline in headless Chrome and encoded with ffmpeg. The music and the sound design are original and synthesized from scratch in the same browser (Web Audio OfflineAudioContext): no samples, no downloaded audio, nothing to license.

One idea per scene, 4-5 s each, one camera move per scene (a quick ease-out that settles before the cut), short dissolves on the cuts, no whips or rapid montages. Long terminal output streams faster rather than being cut. Each scene has one plain-English caption at the top, fully on screen for at least 3 s; below it, the real product.

s shows caption
0-4.5 the demo game's icon, "Done"; the stores' to-do list line by line; one rejection mail (Guideline 2.1) Your app is done. The stores are not.
4.5-9 an empty folder; bunx storebound init is typed; the files it creates list in storebound takes it from an empty folder.
9-14 the prompt "Get my app ready for both stores."; storebound release plan 1.0.0: 25 steps in fix order You ask once. It plans every step.
14-19 the demo game's store text in 4 languages; its renders in 7 store sizes x 4 languages Store text and screenshots. Every language, every size.
19-23.5 play products --dry (174 regions), then catalog diff (175 / 174 region prices, 0 mismatches) In-app products on both stores, priced in 175 countries.
23.5-28.5 the scan's declarations proposal: detected answers with file:line, one "ask owner" line highlighted; 764 Data safety answers The forms, answered from your code. It asks what it can't know.
28.5-33.5 storebound scan: three findings, each with a plain reason; fixed, the re-scan is clean It catches rejections before Apple does.
33.5-38 the desktop app's Portfolio: every app of three studios, App Store and Google Play per app, rollout %, crash-rate sparklines Stop switching between two consoles. Every app, both stores, one window.
38-42.5 the Growth chart (visx) with the pointer sweeping across it, the crosshair and tooltip moving day by day; then the Health tab's crash rate, swept the same way Installs, conversion and crashes, charted.
42.5-47 the Prices tab: products x key territories, both stores' prices per country, the gaps between them marked Products and prices on both stores, side by side.
47-51.5 the release timeline with both stores on one track, then Store readiness: "No blockers" Both stores, one view. Ready for review.
51.5-55.5 "Submit for Review" with the cursor resting on it (it never clicks), then the end card: storebound.dev, Open source · CLI · Desktop app You press Submit. That's it.
file what
script.js the timeline: scenes in seconds, camera moves, captions, every line shown, the sound cues
desktop.ts the desktop frames: apps/desktop's Vite dev server in fixture mode (VITE_FIXTURES=1, example.com-style data), captured headlessly in dark at 1280x800 @2x with the dev markers hidden, plus boxes.json (callout targets, the hover sweeps) -> out/desktop/. The chart hovers are real: the mouse moves across the chart in small steps and a frame is taken for every day the tooltip shows; the video moves its pointer the same way and shows the day it has reached
index.html + teaser.js the picture; window.teaser.seek(t) sets every element for time t
music.js music (D major, one chord per scene: pads, a slow soft pluck, a quiet sub) and soft sound design: a bell and an airy swell on each scene change, key clicks, quiet ticks, chimes for the fixes
render.ts frames at 60 fps blended to 30 fps -> ffmpeg (H.264 high, yuv420p), sound -> loudnorm (-16 LUFS, -1.5 dBTP), mux, poster, the 1280x720 web version
icons/ the mouse cursor and the UI icons: Phosphor files copied unchanged by bun tools/site-icons.ts (no hand-written SVG; CI checks it)

Every CLI line in the video is real output, and tests/teaser.test.ts runs each command and checks every line (the clock prefix and the "(0s)" timer left out):

  • storebound init in an empty temp folder.
  • storebound release plan 1.0.0, play products --dry and catalog diff in that folder, with the stores answered by tests/helpers/teaser-store-mock.ts (preloaded through a bunfig.toml in the folder, so the children release plan starts use it too; nothing reaches the network): a brand-new app record with nothing on it for the plan and the dry run, then the two products on both stores for the diff. Regions: the App Store's 175 storefronts, Google Play 174 (the count Play answered in a recorded read-only run).
  • storebound scan of tests/fixtures/scan/teaser (findings, declarations proposal) and of teaser-fixed after the fixes, and the Data safety answer count of storebound check.

The plain reasons under the findings and the callouts on the desktop frames are annotations, set apart from the CLI text. The store text is examples/demo-game/store/shots/copy.json, the screenshots its real renders, the app icon its store/icon/icon.png. The mail row is fictional: no real names or addresses, no mail-app branding. The test also checks the timing (scenes 4-5 s, captions on screen at least 3 s, 50-60 s in total, 16:9 only) and that every desktop frame a scene names is one desktop.ts captures, and, where they were captured, that each file is there (2560x1600 JPEG, one sweep frame per hovered day).

Render

Needs Bun, ffmpeg, Playwright (repo devDependency; Playwright's Chromium or an installed Google Chrome) and the demo game's store renders:

cd examples/demo-game && bun serve.ts & bun ../../cli/index.ts shots capture && bun ../../cli/index.ts shots fonts && bun ../../cli/index.ts shots render
# from the repo root
bun media/teaser/render.ts > media/teaser/out/render.log 2>&1 &   # master, sound, poster, web version: about 15 min
bun media/teaser/render.ts --desktop                                # capture the desktop app frames again (after a UI change)
bun media/teaser/render.ts --stills 2,12.5,30                       # PNG stills in out/stills for a quick layout check
bun media/teaser/render.ts --serve --port 8750                      # live preview: /index.html?play=1 (or ?t=12.5)

Outputs (gitignored) in media/teaser/out/: teaser-1920x1080.mp4 (master), teaser-web.mp4 (1280x720, about 6 MB) with poster-web.jpg, teaser-1920x1080-silent.mp4, poster-1920x1080.jpg, music.wav.