Motion

Cowork UI Kit's motion vocabulary — durations, easings, choreography. All tokens respect prefers-reduced-motion per WCAG 2.2.

Iter 40A · v0.5 · 2026-05-20

Duration

TokenValueUse
--duration-instant0msSnap (a11y fallback)
--duration-fast120msHover, tap, exit
--duration-normal200msDefault · color, tooltip
--duration-slow320msModal, drawer enter
--duration-slower480msPage surface change
--duration-deliberate800msHero, full route

Easing

TokenCurveUse
--ease-out0.16, 1, 0.3, 1Most exits, modal in
--ease-in0.7, 0, 0.84, 0Most entries, modal out
--ease-in-out0.65, 0, 0.35, 1Accordion, tab
--ease-snap0.4, 0, 0.2, 1Utility default (M3 std)
--ease-spring0.34, 1.56, 0.64, 1Confirm, success
--ease-emphasized0.2, 0, 0, 1Hero, page transition
--ease-linearlinearSpinner, progress

Patterns

1 · Hover lift

Button rises 2px on hover. Affordance hint — element is interactive.

transform · 120ms · ease-out
trigger: :hover

2 · Click press

Button compresses on press. Tactile feedback for fingers/cursor.

transform · 120ms · ease-snap
trigger: :active

3 · Modal entry

Backdrop fades + dialog scales 0.92 → 1. Slow + emphasized for focal moment.

opacity + scale · 320ms · ease-emphasized
trigger: click

4 · Toast slide-up

Snackbar enters from bottom with fade. Non-blocking confirmation.

opacity + slide 16px · 200ms · ease-out
Saved · 2 sec
trigger: click → auto-hide 2.4s

5 · Skeleton shimmer

Gradient slides across placeholder. Loading state — essential, exempt from reduce.

background-position · 1.4s · linear · loop
trigger: always (motion-essential)

6 · Accordion expand

grid-template-rows trick animates height without JS measurement. Symmetric ease.

grid-template-rows · 200ms · ease-in-out
Hidden content reveals smoothly. Works on dynamic-height content because grid-row interpolates fr.
trigger: click

7 · Drawer slide

Side panel enters from right edge. M3 emphasized curve for focal surface change.

translateX · 320ms · ease-emphasized
Drawer content
trigger: click

8 · Tab indicator

Underline slides under active tab. Spatial continuity — tab is one shared element.

transform + width · 200ms · ease-out
Overview Activity Settings
trigger: click tab

9 · Focus ring

Ring fades in instead of jumping. Visible focus is mandatory (WCAG 2.4.7).

outline · 120ms · ease-out
trigger: :focus

10 · Spinner

Indeterminate loading. Linear so it doesn't seem to speed up/slow down.

rotate · 0.8s · linear · loop
trigger: always (motion-essential)

11 · Progress

Bar fills with ease-in-out so deceleration suggests target. Indeterminate variant loops.

width · 2.4s · ease-in-out · loop
trigger: always (motion-essential)

12 · Stagger list

List items appear sequentially. 50ms delay between each item — perceived as orchestrated.

opacity + slide · 200ms · ease-out · 50ms stagger
First item
Second item
Third item
Fourth item
Fifth item
trigger: load + click

13 · Spring confirm

Success checkmark overshoots then settles. Delight for completed action.

scale 0→1 · 320ms · ease-spring
trigger: load + click

14 · Page transition

Outgoing page slides up + fades, incoming slides up into place. Deliberate hero motion.

opacity + slide 32px · 800ms · ease-emphasized
Page A
Page B
trigger: click

15 · Card hover

Card scales 1.03 + tonal shadow. Brand-tinted shadow signals depth, not just elevation.

transform + shadow · 200ms · ease-out
Hover me
trigger: :hover