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
| 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.
Modal + backdrop
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.