# Motion

Durations and easings for transitions, and how reduced motion is handled.

Motion in the platform is functional: it shows where an overlay came from and confirms that
something changed. It is never decorative.

| Token | Value |
| --- | --- |
| `--duration-enter` | `200ms` |
| `--duration-exit` | `120ms` |
| `--duration-fast` | `150ms` |
| `--duration-base` | `250ms` |
| `--duration-slow` | `400ms` |
| `--ease-enter` | `cubic-bezier(0.16, 1, 0.3, 1)` |
| `--ease-exit` | `cubic-bezier(0.4, 0, 1, 1)` |

## Overlays

Every overlay (dialog, sheet, popover, menu, tooltip) shares one asymmetric timing: it **enters**
in `--duration-enter` (200ms) with `ease-enter` (a long ease-out) and **exits** in
`--duration-exit` (120ms) with `ease-exit` (a short ease-in). Dismissal feels immediate; arrival
is legible. The components wire this up through Base UI's `data-starting-style` and
`data-ending-style` attributes.

```tsx
className =
  "transition-opacity duration-(--duration-enter) ease-enter data-starting-style:opacity-0 data-ending-style:duration-(--duration-exit) data-ending-style:ease-exit"
```

## Everything else

Hover, toggles and small reveals use `--duration-fast` (150ms). Larger layout changes such as
a collapsing sidebar use `--duration-base` (250ms). Reserve `--duration-slow` (400ms) for
content that moves a long distance.

## Reduced motion

When the user asks the system for reduced motion, `styles.css` collapses every animation and
transition to near zero. Elements still land on their final state, so nothing is left
half-transformed. You do not need to handle `prefers-reduced-motion` in components.
