How METRONOME
was made
METRONOME is a fictional motion design studio that treats timing as its entire product. The audience is broadcast and brand producers deciding who to trust with an ident. The page has one job: prove the studio's taste in motion by being a piece of motion — the visitor's scroll is the playhead of the showreel.
Palette
Type
The voice of the studio: geometric but with cut, slightly eccentric terminals — a grotesk that behaves like a display face at 200px. Used massive and tight (-0.035em) for the hero, showreel words, and section titles; tabular figures drive the timecode HUD.
Deliberately unremarkable at small sizes so the display face keeps all the attention. Uppercase 11px labels at +0.16em tracking do the wayfinding.
Techniques
The signature element. One GSAP master timeline (14 timeline-seconds, ease "none" at the root) is bound to a single ScrollTrigger with pin: true and scrub: 0.8 over 4.5 viewport-heights of scroll. Five scenes — film leader countdown, beat-stepped square scale-up, clip-path mask reveal of TIMING, split-flap character flips, and the FIN lockup — are absolutely stacked and toggled with autoAlpha set() calls at exact times, so scrubbing backwards replays perfectly with no state pollution. The HUD's timecode (24 s × 24 fps), scene counter, and progress bar are driven from the trigger's onUpdate; the end value is a function of innerHeight with invalidateOnRefresh so resize never desyncs pin spacing.
An SVG pendulum swings ±16° on a 0.5 s sine yoyo — exactly 120 beats per minute. Each extreme fires an onRepeat that flashes the header tick dot, so the whole page keeps time.
Second-read detail: the HUD's TEMPO field maps scroll velocity onto BPM with lerp smoothing and decays back to 120 when you stop. Scrub too fast and it flags you — "RUSHING".
No raster assets: SVG leader crosshair and pendulum, CSS clip-path mask, DOM split-flap characters with 3D rotationX and a recessed transform origin, div wipe bars. Fonts and GSAP are the only external resources.
prefers-reduced-motion or a failed GSAP load adds a static class: the pin is never created, the FIN lockup shows as a poster frame, and all CSS animation is killed via media query. Content order stays intact without JavaScript.
Iteration log
Pass 1 — Craft
- Caught a real palette violation in headless screenshots: the fixed header used mix-blend-mode difference, which rendered the logo and BPM chip olive-yellow over the blue scenes and the paper Work section. Replaced with an IntersectionObserver that flips the header to ink only while paper is under it.
- Raised HUD label opacity to .92 and scene tags to .9 — at .62 they fell to roughly 3:1 against the electric blue during the MASK scene.
- Unified all hover easings on one curve — cubic-bezier(.22,1,.36,1) — where three near-duplicates had crept in.
- Aligned the HUD top row below the fixed header (64px) so REC and the logo never collide.
Pass 2 — Depth
- Added the TEMPO velocity readout with the "RUSHING" easter egg — the reel now judges your scrubbing like a conductor.
- Gave the beat notches a bar structure: every fourth notch is full-height, so the progress bar reads as 4/4 time.
- Doubled the FIN pulse ring and offset the second by half a beat for a syncopated ending.
- Leader countdown numbers were hard-swapping; each now lands with a 1.22→1 scale pop so the count feels struck, not toggled.
- Square scale-up now enters with back.out(2.5) and pulses via steps(2) before the expo.inOut fill — three distinct musical gestures instead of one zoom.
Pass 3 — Hardening
- 375px: pendulum hidden, BPM counter reduced to its dot, work rows collapse to a two-line grid, showreel words re-clamped so EVERYTHING. never wraps.
- Verified reduced-motion path never registers ScrollTrigger — no pin spacing is added, page is a plain document.
- End value made a function with invalidateOnRefresh; anticipatePin:1 removes the one-frame jump on fast scroll into the pin.
- Chanel rule: the FIN lockup carried both an ® mark and the pulse dot — two competing marks, ugliest in the reduced-motion poster frame. The ® went.
- Verified in headless Chrome at 1440 and 375: pin start/end exactly 4.5 viewport-heights, zero horizontal overflow, zero console errors, reverse scrub replays clean.