A landing page whose opening shot is under the reader's thumb.
The hero above is one pre-rendered clip whose currentTime is
driven by scroll position. No autoplay, no video player, no library —
about 13 KB of JavaScript and a file the browser already knows how to
decode.
Complete without the video
Delete every .mp4 and this page still reads. The poster
stays, the copy still lands. Footage is an upgrade, never a
dependency.
Runs from a file
Double-click index.html. No server, no build step, no
install. The engine takes a different code path on file://
precisely so this works.
Themed by tokens
Every colour resolves from a CSS custom property. Swap the palette
top-right, or edit :root once and the whole page follows.
The small clip is the fast one.
We drove real scroll in a real browser and recorded how many of the clip's frames actually reached the screen. The 1536×832 master loses frames because the decoder cannot service scrub seeks fast enough. The 960×520 clip in this pack loses none — and weighs a third as much.
Reproduce it yourself — the method and the
harness are in README.md. Do not accept these numbers on
our say-so.
Bring your own five seconds.
Replace assets/act1.mp4 with your own footage, extract a
poster from its first frame, and you are done. The encode settings
that matter — short GOP, faststart, no audio — are spelled out in the
README, with the exact ffmpeg commands.
Want more than one act? The engine takes an
array of scenes and cross-dissolves between them. Add entries to
HERO_CONFIG.scenes.

On a portrait phone, you see the middle quarter.
A landscape clip inside a tall viewport is cropped by
object-fit: cover — about 75% of the width goes. This pack
ships a smaller landscape clip for mobile, not a portrait one, because
a native 9:16 render was never proven. Frame your shot so the subject
lives in the centre, or supply your own portrait encode.