Motion

The motion vocabulary of the 2026-09-02 airmond.com rebuild, as tokens in dist/css/airmond.css (--motion-*) and dist/ts/tokens.ts (motionWeb). Six durations, five curves, one damping number, and two rules that matter more than any of them. The app keeps its own shorter motion scale (90 / 160 / 240 / 420); this page is marketing web: landers, decks, anything that reveals itself on scroll.

Tokens

TokenDurationEase (CSS)GSAPUse
--motion-arrive700mscubic-bezier(0.22, 1, 0.36, 1)power3.outanything entering the page
--motion-land600mscubic-bezier(0.16, 1, 0.3, 1)expo.outelements that settle: cards, pills, check marks
--motion-micro180mscubic-bezier(0.25, 0.46, 0.45, 0.94)power2.outhover, focus and press feedback
--motion-press-in90msease-outpower1.outthe press itself: scale 0.98
--motion-press-out260mscubic-bezier(0.34, 1.56, 0.64, 1)back.out(1.6)the release: a small spring back to 1
--motion-ambient-min / -max4s to 8scubic-bezier(0.37, 0, 0.63, 1)sine.inOutthe one or two things allowed to breathe: a waveform, a portrait row
--motion-scrub-damping0.6ScrollTrigger scrublag for scroll-bound motion (the hero parallax, the steps highlight)
--motion-reduced200mseaseunder prefers-reduced-motion every state change is this opacity fade, with no travel

The eases ship as --motion-ease-arrive, --motion-ease-land, --motion-ease-micro, --motion-ease-press-in, --motion-ease-press-out and --motion-ease-ambient, and as Tailwind ease-arrive, ease-land, ease-micro, ease-press-out, ease-ambient.

Live

Each box plays its token once. Hover and press the button for micro and press; the portrait breathes on the ambient curve (1.00 to 1.015 over 6s). Under prefers-reduced-motion this page does what every Airmond surface does: the boxes fade in 200ms with no travel and the portrait holds still.

Arrive, 700ms
24px up, opacity 0 to 1
Land, 600ms
settles from 0.96
Micro, 180ms
2px lift, colour step
Press, 90ms in / 260ms out
Hover lifts 1px on coral-hover; the press is 0.98 and the release springs back.
Ambient, 6s
Ada, breathing at 1.5%
The portrait row is phased by index so it never moves in lockstep.

The reduced-motion rule

Reduced motion is stillness, not a shorter version. Under prefers-reduced-motion: reduce no timeline is built at all: nothing is hidden, nothing travels, the film stays on its poster, nothing loops, hover and press keep their colour change and lose their transform. The one motion left is the 200ms opacity fade on a state change (a field appearing, an error, success), because a block that appears from nothing reads as a glitch.
@media (prefers-reduced-motion: reduce) {
  .loop, .breathe, .dot { animation: none; }
  .btn, .tile { transition-property: background-color, box-shadow, opacity, color; }
  .btn:hover, .btn:active, .tile:hover { transform: none; }
  .state-change { animation: fade var(--motion-reduced) ease both; }
}

The budget

Where each token is used on the landing page

MomentTokenWhat moves
The arrival (0 to 1.4s)arrivethe pill (0.4s), the headline line by line (24px up, 0.7s, stagger 0.08), the sentence, the card rising 16px as its shadow blooms, the film's left fade opening from 60% to 31%
Sections enteringarrive, landtiles rise 32px on a diagonal (stagger 0.09); icons materialise from 0.85 with a small settle; check marks draw themselves (0.45s, 120ms apart)
The sign-up cardarrive, micro, pressthe recap and trust blocks grow in over 260ms; a refused number shakes the field 2px twice; success draws a check in confirm blue over 0.6s
Ambientambientwaveform (only while on screen), portrait breathing (6s, phased), the live chip's dot (2.4s)
Scrollscrub-dampingthe hero film scales 1.00 to 1.08 from its bottom edge and slides 64px; the three steps light in turn, never pinned