storebound/media/teaser
2026-10-21 05:39:45 +07:00
..
icons teaser v8: a 58 s story instead of a feature list (the game is done; the stores pile up; one missing line; hand it to your AI; a montage of builds, screenshots, products, forms, consoles; the scan turns green; one button is yours; Waiting for review; the end card), one short line per scene, cuts on the 120 BPM beat; music rewritten for the arc (calm, tension, near silence, a driving build, a stop, a resolve), mastered with one gain instead of dynamic loudnorm; the pile shows real console plan, Data safety CSV and price sheet lines, the builds beat real apple / play build dry runs; desktop.ts captures submit-ready (Send for review before the press); tests check every line, the beat-aligned cuts and the caption times; two unused teaser icons dropped 2026-10-13 04:48:33 +08:00
desktop.ts teaser: render.ts --scale 2, the 3840x2160 master for 4K uploads (same page at device scale 2, desktop frames captured at @3x into out/desktop@3x, demo game renders at 2x into out/assets@2x, H.264 high about 40 Mbps, AAC 320 kbps, +faststart; no web version); desktop.ts captureDesktop takes a scale and an output folder 2026-10-14 05:31:31 +08:00
index.html teaser: no text overflows anywhere: teaser.textCheck(t) checks every visible text node (scroll size within its element, its box inside its card, every card in frame as drawn), render.ts --animatic runs it at every frame of the whole teaser into animatic-checks.json and tests/teaser.test.ts requires zero problems; reject titles shortened ('No demo account', 'Manifest refused'); fixes it found: terminal and pile rows wrap instead of being cut with an ellipsis, the scan findings wrap, the pile shows only the rows that fit whole (no streaming past the edge), caption, edge word, labels and end card line heights fit their glyphs, builds and products push straight in so the terminal stays in frame 2026-10-14 05:47:42 +08:00
music.js teaser: the reject shot redone (7-11 s, 4 s): the common rejections storebound catches as real scan finding cards landing one per beat (2.1(a) demo account, 5.1.1(v) account deletion, 5.1.2(i) ATT from tests/fixtures/scan/teaser; ITMS-91064 from the new teaser-manifest fixture), guideline + one plain line each, then our own REJECTED stamp hits the stack on the beat at 9.5 s, no shake (one 4 px 1-frame jolt), a 3% push, the picture darkens into the cut; caption 'Rejected. Again.'; later shots +1.5 s (42.5 s, every cut on a beat, music follows the scenes, a thud per card and a hit on the stamp); render.ts --animatic --range a,b and --sheet a,b,fps, and the reject cards' boxes per frame in animatic-checks.json; tests: real finding lines, beat timing, and every card inside 6% safe margins at every frame 2026-10-14 05:47:42 +08:00
poster.jpg teaser v9 final with the new reject shot: 1920x1080 master, web version and posters from the end card; site teaser and poster (cache key v=6), README poster 2026-10-14 06:10:39 +08:00
README.md teaser: no text overflows anywhere: teaser.textCheck(t) checks every visible text node (scroll size within its element, its box inside its card, every card in frame as drawn), render.ts --animatic runs it at every frame of the whole teaser into animatic-checks.json and tests/teaser.test.ts requires zero problems; reject titles shortened ('No demo account', 'Manifest refused'); fixes it found: terminal and pile rows wrap instead of being cut with an ellipsis, the scan findings wrap, the pile shows only the rows that fit whole (no streaming past the edge), caption, edge word, labels and end card line heights fit their glyphs, builds and products push straight in so the terminal stays in frame 2026-10-14 05:47:42 +08:00
render.ts teaser: no text overflows anywhere: teaser.textCheck(t) checks every visible text node (scroll size within its element, its box inside its card, every card in frame as drawn), render.ts --animatic runs it at every frame of the whole teaser into animatic-checks.json and tests/teaser.test.ts requires zero problems; reject titles shortened ('No demo account', 'Manifest refused'); fixes it found: terminal and pile rows wrap instead of being cut with an ellipsis, the scan findings wrap, the pile shows only the rows that fit whole (no streaming past the edge), caption, edge word, labels and end card line heights fit their glyphs, builds and products push straight in so the terminal stays in frame 2026-10-14 05:47:42 +08:00
script.js console verify: an older page's long labelled radio still counts from page text when the sheet answers Yes / No; tests and the teaser follow the new sign-in details question and the added App Privacy step 2026-10-21 05:39:45 +07: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: no text overflows anywhere: teaser.textCheck(t) checks every visible text node (scroll size within its element, its box inside its card, every card in frame as drawn), render.ts --animatic runs it at every frame of the whole teaser into animatic-checks.json and tests/teaser.test.ts requires zero problems; reject titles shortened ('No demo account', 'Manifest refused'); fixes it found: terminal and pile rows wrap instead of being cut with an ellipsis, the scan findings wrap, the pile shows only the rows that fit whole (no streaming past the edge), caption, edge word, labels and end card line heights fit their glyphs, builds and products push straight in so the terminal stays in frame 2026-10-14 05:47:42 +08:00

storebound teaser (v9, 42.5 s, 16:9)

The v8 story cut tight: the game is done, the stores pile up work, one line gets it rejected, so your AI does it, and you press Submit. Editing rules: frame 0 already moves and shows the product (no black, no calm intro); nothing holds still longer than 0.8 s; every shot does one thing in 2-4 s and cuts when that thing completes (a line lands, a number lands, a check turns green); captions are at most six words and on screen for at least 2 s; the camera pushes toward the thing that changes; the last 4 s are the end card with npx storebound init typed out big and storebound.dev. Real product footage only. 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 sound design are synthesized in the same browser (Web Audio OfflineAudioContext): no samples, nothing to license.

120 BPM: every cut is a hard cut on a beat (whole half seconds), with a sound accent on each. Before any final render, make the animatic (--animatic: a 960x540 draft with sound, a one-frame-per-second contact sheet and the shot list) and get the owner's OK.

s shows text music
0-3 the demo game's own screens rush past, a push in Your game is done. drives from frame 0: kick, bass, arpeggio
3-7 real store work lands one card per beat: App Privacy answers and steps, the Data safety CSV (768 rows), screenshot sizes, price sheets Then come the stores. tension: B minor pulse, kicks, a thud per card
7-11 the common rejections storebound catches, as real scan finding cards landing one per beat (2.1(a) "No demo account", 5.1.1(v) account deletion, 5.1.2(i) ATT, ITMS-91064 privacy manifest), every card inside 6% safe margins; at 9.5 s our own REJECTED stamp hits the stack; the picture darkens into the cut Rejected. Again. a low boom, a thud per card, a hit on the stamp
11-13.5 one request typed to the AI agent, sent on the beat So my AI did it. a short drop: an impact, half-time beat, key clicks, a swell
13.5-16.5 apple build --dry, play build --dry: build 52, versionCode 52 Builds. the drop
16.5-19.5 the demo game's renders: 7 store sizes x 4 languages fill in Screenshots, every size. + hats
19.5-22.5 play products --dry, catalog diff (175 / 174 region prices, 0 mismatches) Products, 175 countries. + claps
22.5-25.5 the scan's declarations proposal, the Data safety rows ticking, 768 answers Forms. + sixteenths
25.5-28.5 console plan apple-app-privacy, then the desktop app's plan panel, the owner's Publish ringed Consoles. + lead
28.5-32.5 storebound scan: five findings turn green one per beat, the clean re-scan Nothing left to reject. a chime per fix
32.5-34.5 the desktop app's Send for review, the camera pushes onto Submit, the pointer arrives You press Submit. the music stops
34.5-37.5 the click, then the app's own "Waiting for review" (same line) the resolve
37.5-42.5 the logo, npx storebound init typed out, storebound.dev; holds 4 s (none) a confident kick and bass on D, the chord; fades over the last 1 s

The demo game has 4 languages (en, tr, ja, ar), so the screenshot beat says "every size", not a language count. The video shows no drawn system dialog and no mail: between the click and "Waiting for review" the real app shows its own dry-run plan and then the system's confirm dialog, which the story skips.

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 (ring and pointer targets) -> out/desktop/. The console plan panel gets the real storebound console plan apple-app-privacy --json of a fresh storebound init folder; the send-for-review frames press "Read state" and pick build 52 as the owner would (submit-ready), and the "Waiting for review" frame serves the fixture's apple status with the new submission waiting. It also captures the frames the site uses (site-shots.ts)
index.html + teaser.js the picture; window.teaser.seek(t) sets every element for time t
music.js music and sound design, one section per part of the arc (see the table)
render.ts frames at 60 fps blended to 30 fps -> ffmpeg (H.264 high, yuv420p); sound: one gain to about -16 LUFS with the true peak at or below -1.5 dBTP (no dynamic normalization, so the quiet parts stay quiet), 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), in a fresh storebound init folder with two products:

  • storebound console plan apple-app-privacy (offline): the answer sheet and step lines of the pile, the plan lines of the consoles beat, the never-press list and the owner's final button.
  • storebound play data-safety --dry (the CSV lines), storebound check (768 rows), storebound prices ppp --offline --dry (the price rows).
  • storebound apple build --dry and storebound play build --dry in a minimal Capacitor project.
  • storebound play products --dry and catalog diff, with the stores answered by tests/helpers/teaser-store-mock.ts (preloaded through a bunfig.toml in the folder; nothing reaches the network).
  • storebound scan of tests/fixtures/scan/teaser (the reject cards' 2.1(a), 5.1.1(v) and 5.1.2(i) findings; the ITMS-91064 card from teaser-manifest, all five findings, the declarations proposal) and of teaser-fixed after the fixes.

The test also checks the timing (every cut on a half-second beat, scenes 3-6 s, the montage at 19-37 s speeding up with cuts rather than dissolves, captions of at most 8 words fully on screen at least 2.5 s inside their scene, 56-62 s in total, 16:9 only), that the game screens and screenshot tiles are the demo game's own, and that every desktop frame a scene names is one desktop.ts captures (where they were captured: each file there, 2560x1600 JPEG).

Render

Needs Bun, ffmpeg, Playwright (repo devDependency; Playwright's Chromium or an installed Google Chrome) and the demo game's store captures and 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 20 min
bun media/teaser/render.ts --scale 2 > media/teaser/out/render-4k.log 2>&1 &   # 3840x2160 master for X (about 40 Mbps, AAC 320k): about 45 min
bun media/teaser/render.ts --desktop                                # capture the desktop app frames again (after a UI change)
bun media/teaser/render.ts --animatic ../storebound-dist/teaser-v9-animatic  # draft.mp4 (960x540), contact-sheet.png, shots.md: for the owner's OK
bun media/teaser/render.ts --animatic <dir> --range 5,14 --sheet 6,12,4      # one region only, contact sheet at 4 frames/s; writes the reject cards' boxes to out/animatic-checks.json (safe-margin test)
bun media/teaser/render.ts --stills 2.5,13.5,38                     # PNG stills in out/stills for a quick layout check
bun media/teaser/render.ts --sound                                  # the music only (out/music.wav)
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.7 MB) with poster-web.jpg, teaser-1920x1080-silent.mp4, poster-1920x1080.jpg, music.wav.