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.