Motion
Motion is a perceptual scale, so it stays short. It also carries a hard rail: when the operating system asks for less motion, everything collapses to a single frame.
import from src/brand/effects.css · src/system/theme.css
Reduced motion is not optional
prefers-reduced-motion is honoured globally in
src/system/theme.css: every animation and
transition collapses to one instant frame. That block is deliberately unlayered so it outranks
the utilities without needing !important.
It has one blind spot, and it matters. The global rule shortens a duration, but it does not zero a delay, and it cannot reach unlayered brand classes. So any effect built on a delay or an ambient loop opts out for itself. The hero's copy would otherwise sit invisible for its full four-second cue, and the mark's four letters would land stacked on top of each other. Both handle it locally.
Scroll reveal
Content is attached to the scroll. A view()
timeline scrubs each .reveal in as it enters
from the bottom and back out as it is scrolled up, so the progress tracks the scroll position
rather than firing once. No observer, no script. Where scroll-driven animations are
unsupported the content just shows, and reduced motion pins it visible.
.reveal · animation-timeline: view()
opacity 0, translateY(2rem) → opacity 1, none. animation-range: entry 0% cover 32%.
The signature moves
The hero's layered reveal
Yellow base, rust rising from the bottom, charcoal sweeping in from the right. Four seconds before the copy arrives. It is the one place on the site that asks the visitor to wait.
The mark convergence
H, O, Z and A start spread across the footer and drift onto centre over ten seconds. Fires once, when the footer scrolls into view.
The endeavor morph
The endeavors section is a scroll story: a particle cloud on the right re-forms from one shape to the next (sphere, octahedron, cube, torus) as each chapter centers. Scroll-driven, not ambient. Under reduced motion it holds a shape and only re-forms on scroll, never spins.
The marquee
Two identical tracks translate by exactly half the pair, so the loop has no seam. Frozen entirely under reduced motion.
Rules
- Motion earns its place by explaining a change of state or a change of place. Decoration is the exception, not the default.
- Anything ambient or delayed handles its own reduced-motion case. The global rule will not cover you.
- Never hide content behind a hover. Hover may add, it may not be the only way to read something.
- Reveals are scroll-linked, not triggered: they track the scroll both ways, in on the way down and out on the way up. Scrub the progress, never fire-and-forget.