Critical edition · study score
How STAVE was written
The agency site as an orchestral score — scroll conducts the page.
1 The Concept
STAVE treats a portfolio site as a printed orchestral score. The page is the paper: cream stock, notation-ink type, staff lines as the literal layout grid. The visitor is the conductor — scroll velocity is read as a tempo (♩ = a number that rises when you flick and settles when you rest) and translated into a dynamic marking from pp to ff. That same reading scales every animation's easing, so the page genuinely plays faster under an agitated hand and relaxes — ritardando — when you settle into a movement.
The information architecture is a programme in four movements: I. Overture (the brand), II. The Ensemble (six services as instrument parts stacked into a system score), III. Repertoire (three projects as programme entries), IV. Coda (contact, closing on a double barline marked Fine). Program-note placards introduce each movement the way a concert booklet would, and keys 1–4 turn straight to a movement.
Honestly stated intent: the metaphor is a frame for restraint. One paper color, one ink, red spent only on dynamics, ochre only on rehearsal marks — so the typography and the rhythm of the staff grid carry the whole design.
2 Cited References
- Museum Department — placard/audio-guide framing and a command palette. Adapted: bordered programme-note placards introduce each movement, and the keyboard-first navigation (keys 1–4 jump to movements, announced to screen readers) replaces the palette.
- NRG Data Center — chaptered scrollytelling under fixed oversized headlines. Adapted: each movement's numeral + title is a sticky heading that stays pinned while its content scrolls beneath, so you always know which movement is playing.
- Otherkind — giant wordmark with live status elements. Adapted: the hero is a giant clef-crossed NOMADIC OWLS wordmark, and the live element is the fixed tempo console (♩ = your scroll speed, tempo word, dynamic mark).
3 Design System
Palette
- Score cream
#FAF6ECthe paper — page background - Notation ink
#191713type, staff lines, chrome - Conductor red
#B02E2Edynamics ONLY — pp→ff marks, hairpins, sfz - Rehearsal ochre
#C08A2Dsparse — rehearsal letters, kickers, part numerals
Type
Playfair Display — display. Engraver's
elegance for the wordmark (900), movement titles (italic), lyric lines and dynamic marks
(italic 700, the only red type). Self-hosted via @fontsource/playfair-display.
Work Sans — body and labels. 400 for
running text, 500/600 for part names, chrome and the tempo console. Self-hosted via
@fontsource/work-sans.
Spacing — the staff as grid
One beat = 28px. Body line-height is exactly one beat; every vertical
margin and padding is a multiple of it. Staff systems are painted as five hairlines one
beat apart (a repeating-linear-gradient), offset by
--baseline-shift: 21px so text baselines land on the lines rather than
floating between them. Section rhythm: headings enter on the beat, placards a half-beat
later — the layout is quantized.
4 Tech & Motion
- Tempo console. A
requestAnimationFrameloop measures scroll speed in px/s, smoothed with an asymmetric exponential average (fast attackk=0.28, slow releasek=0.035— so flicks spike instantly and settle gradually). It maps to♩ = 66 + v·0.032(clamped 66–200), then to a tempo word (Grave→Presto) and a dynamic (pp→ff). - Easing follows dynamics. The same loop writes a CSS custom property
--tempo(0.45 at Presto, 1.5 at Grave). Every transition duration is declared ascalc(base × var(--tempo)), so fast scrolling makes reveals snap (agitato) and resting makes them stretch (ritardando). No animation library — CSS transitions plus one rAF loop. - Movement choreography. Reveals are
IntersectionObserver-cued (.cue → .played), staggered per part by beat-multiples of delay, also scaled by--tempo. Sticky movement headings pin under a cream gradient. - Staff grid. Pure CSS — no images: a repeating gradient paints five
1px lines one beat apart; a
::beforepseudo-element draws the system barline joining them. - Keyboard. Keys 1–4 scroll to movements, move focus to the movement
heading (
tabindex="-1"), and announce via anaria-livestatus region. Skip link, semantic landmarks, visible focus rings throughout. - Reduced motion. Under
prefers-reduced-motion: reducethe rAF loop never starts, the console stays a static ♩ = 76 Andante, all cues render played, and scrolling is instant. The loop also pauses onvisibilitychange. - No video — by design. STAVE's motion is typographic choreography: the score metaphor is about ink on paper responding to a conductor, so all movement is procedural (scroll-driven easing, staggered type). A looping video would add weight and break the "printed page" illusion; the three stills are treated as tipped-in plates.
5 AI Assets
Three stills, generated with GPT Image 2 via the Higgsfield CLI and
served as WebP. No Kling video was generated for STAVE — motion is procedural typographic
choreography (see §4). Prompts verbatim from shared/assets/manifest.json:
score-texture.png · GPT Image 2 (via Higgsfield CLI) · hero score backdropClose-up of a hand-engraved orchestral score on cream paper, elegant black music notation, crescendo hairpins and dynamics markings, a red conductor pencil marking circling one bar, raking warm light showing paper grain, editorial photography, shallow depth of field
conductor-hands.png · GPT Image 2 (via Higgsfield CLI) · movement imageryBlack and white photograph of a conductor's hands mid-gesture with baton, motion blur tracing an arc, dark background, dramatic side lighting, expressive concert photography, no faces, no text
instrument-detail.png · GPT Image 2 (via Higgsfield CLI) · services imageryMacro photograph of orchestral instrument details arranged on cream cloth: violin scroll, oboe keys, french horn valves, cello strings, warm brass and wood tones against soft cream, elegant editorial still life, no text
6 How to Reproduce
- Scaffold Astro v5, static output:
npm create astro@latest→output: 'static', sitehttps://owls-stave.pages.dev. npm install @fontsource/playfair-display @fontsource/work-sans; import only the weights used (400/700/900 + italics; 400/500/600).- Define the beat (
--beat: 28px) and baseline shift; paint staff systems with a repeating gradient; set all line-heights and vertical spacing to beat multiples. - Build the four movements with sticky heads, placards, the six-part system score and
the programme list; copy the three WebP plates into
public/assets/. - Add the conductor script: rAF scroll-velocity loop → ♩/word/dynamic readout →
--tempoeasing scale; IntersectionObserver cues; keys 1–4; reduced-motion and visibility guards. npm run build→ deploy thedist/to Cloudflare Pages.
Designed & built by Claude (Anthropic) for Nomadic Owls. One of ten directions — index at owls-index.pages.dev.