Motion catalogue

Presence motion, one surface at a time

Each section replays one overlay's entry and exit. The slow-motion toggle stretches the duration tokens so the presence curves read, and the reduced-motion toggle confirms the fallback snaps instead of ghosting. The recipes below describe the cascade in src/css/components/.

Recipe matrix

What interpolates during each surface's enter and exit motion.
Surface Interpolates Entry Exit Snaps
status-bar opacity, translate 150 / 200ms, --ease-enter 100 / 150ms, --ease-exit
tooltip opacity 100ms, ease 100ms, ease
flyout (anchored) opacity 100ms, ease 100ms, ease
modal + backdrop opacity, transform, backdrop opacity 150ms, --ease-enter 150ms, --ease-exit
drawer + backdrop opacity, transform, backdrop opacity 200ms, --ease-enter 150ms, --ease-exit --drawer-motion-duration couples the scrim to the panel

Curves under --ease-enter/--ease-exit belong to the open/closed state that owns them (destination state owns the transition). The 100ms toggles deliberately share one list and stay on the CSS default ease; backdrops keep ease but track the panel duration. Exits relying on display/overlay discrete transitions snap on browsers without transition-behavior: allow-discrete.

Status bar

Singleton live region, pinned to the layout viewport. Entry is slower (legible before it settles), exit faster (feedback gets out of the way). background-color intentionally follows state ease, not the presence curves.

Tooltip

Opacity only. A scale around the center moves the arrow tip away from its trigger and reads as a jump on small text, so the anchored surface fades without geometry.

Anchored flyout

Opacity only. Scale around the center would detach the edge attached to the trigger on wide panels, so the anchored menu fades in place and the anchor always stays put.

A centered surface lifts slightly from the page instead of zooming; the translate-only geometry avoids horizontal edge drift on wide panels. Entry decelerates, exit accelerates at the same duration; the native dialog keeps its top-layer semantics.

An opt-out modal (closedby="none", no data-dialog-dismissible) rejects light dismiss: pressing outside (or Replay shake) flashes the actual-dialog-static shake and keeps the dialog open — the feedback quirk that stays on ease, independent of the enter/exit pair. Close it with the button inside.

Drawer + backdrop

The side sheet travels the full drawer width, so the asymmetric recipe is most legible here: entry 200ms decelerating, exit 150ms accelerating. The backdrop shares the panel duration through --drawer-motion-duration and keeps the neutral scrim curve.

Modal replay

Entry decelerates into place; exit accelerates back out, both with a small vertical lift and no scale.

Drawer replay

The panel slides the full width in --duration-slow and exits at --duration; the scrim follows via --drawer-motion-duration.

Invalid light dismiss

Press outside this dialog to see the shake. It stays open; use Close below to exit.