Ethan McNamara

Design

The motion

Every animation here is either answering something a person did, or explaining a mechanism. Nothing loops for decoration. The durations below are read out of this site's own stylesheet as you load the page, and the film curves are read out of the films' source.

Whether to animate at all

The first question is not which easing. It is how often a person will see this.

How oftenExampleDecision
Hundreds of times a dayOpening search with ⌘ KNever animate. A keyboard action should be instant, always.
Tens of times a dayHovering a rowColour only, 160ms, no movement.
A few times a sessionMoving the lens, opening a caseAnimate, under 300ms.
OnceThe first paint of the home pageOne orchestrated moment, then never again this session.

Search on this site does not animate for exactly this reason. Neither does the theme toggle when you reach it by keyboard.

The site's own motion

Five durations do all the work. Hover or focus a specimen to play it; the number beside it is read from the stylesheet, not typed here.

  • Press

    · --d-press

    The only job is to prove the interface heard you. Anything slower feels like lag; anything larger than 3% feels like a toy.

    Every button, link card and control on this site.

  • Reveal

    · --d-reveal

    Small things that appear near the cursor. Fast enough that it never gates the next action.

    Chips, tooltips, the lens callouts.

  • Hover

    · --d-hover

    A colour or border change, never a movement. Movement on hover makes a page feel nervous.

    Rows, frames, nav items.

  • Arrival

    · --d-arrive

    Six pixels and an opacity change. Enough to say something is new, not enough to make you wait for it.

    Sections on first paint, the instrument’s stages.

  • Page

    · --d-page

    A cross-document view transition. It keeps the name mark and the poster frame in place so the site reads as one instrument rather than a stack of documents.

    Every navigation, where the browser supports it.

The two curves

Built-in CSS easings are too weak to read as intentional. These two, and no others.

Entering and leaving

--ease-out:

Starts fast. The interface answers before you have finished the gesture.

Moving across the screen

--ease-in-out:

Accelerates and settles, the way an object with mass would.

Never ease-in. It delays the first movement — the exact moment a person is watching hardest — so the same duration feels slower.

The films

7 product films animate on a single clock: render(t) is a pure function of milliseconds, so seeking backwards restores exactly the same frame. Each one's key gesture is broken down on its own case page.

FilmGesturePhasesEasing
Drive The document lift 500 · 3700 · 500 ms smoothstep, clamped See it
Nudge The send 1250 · 2500 · 800 ms ease-out cubic See it
Review The capture 1000 · 900 · 1100 ms ease-out cubic See it
Blueprint The preview 2400 · 2500 · 2700 ms ease-out cubic See it
Handshake The confirmation 600 · 2000 · 1300 ms ease-in-out cubic See it
Collect The placement 1000 · 400 · 2900 ms ease-in-out cubic See it
Shift The preview of a moved date 1500 · 5000 · 5000 ms ease-in-out cubic See it

ease-out cubic

p => 1 - Math.pow(1 - p, 3)

cubic-bezier(0.33, 1, 0.68, 1)

ease-in-out cubic

p => p < .5 ? 4*p*p*p : 1 - Math.pow(-2*p + 2, 3) / 2

cubic-bezier(0.65, 0, 0.35, 1)

smoothstep, clamped

p => p*p*(3 - 2*p)

cubic-bezier(0.5, 0, 0.5, 1)

With reduced motion on

What changes

Reduced motion is not no motion — it is no movement. Opacity and colour transitions stay, because they carry meaning; anything that travels across the screen is removed.

The lens stops springing and follows your pointer directly. The films switch to their still panels with the written walkthrough. The working models show every stage at once instead of revealing them. The specimens above show their first and last frame side by side. No page transitions run.

Each of those is a designed alternative, not a disabled feature. You can check by turning the preference on and reloading: nothing on this site becomes unusable or empty.