# Motion tokens
Source: https://www.springs.studio/?e=sub*subtle*b.20.0.0.100*140*r70*40&e=std*standard*b.20.0.0.100*200*r70*40&e=emp*emphasized*b.20.0.0.100*280*r70*40&pu=sub.std.std.std.emp.emp.emp
## The set
3 motions, each shipping an entrance and an exit.
- `motion.subtle.enter` — 140ms, cubic-bezier(0.2, 0, 0, 1)
- `motion.subtle.exit` — 98ms, cubic-bezier(1, 0, 0.8, 1)
- `motion.standard.enter` — 200ms, cubic-bezier(0.2, 0, 0, 1)
- `motion.standard.exit` — 140ms, cubic-bezier(1, 0, 0.8, 1)
- `motion.emphasized.enter` — 280ms, cubic-bezier(0.2, 0, 0, 1)
- `motion.emphasized.exit` — 196ms, cubic-bezier(1, 0, 0.8, 1)
## Purposes
Aliases, not copies. Prefer these at call sites.
- `state` → `subtle` (enter and exit)
- `dropdown` → `standard` (enter and exit)
- `tooltip` → `standard` (enter and exit)
- `list` → `standard` (enter and exit)
- `drawer` → `emphasized` (enter and exit)
- `modal` → `emphasized` (enter and exit)
- `toast` → `emphasized` (enter and exit)
## Rules
1. **Entrances decelerate.** Fast at the start, settling into rest. An entrance that accelerates into its resting place is the most common way a set feels wrong, and neither the durations nor the stagger will tell you it is happening. Every token in the JSON reports a `direction` so this is checkable rather than a matter of taste.
2. **Exits are faster and flatter than entrances.** The exit curve is the mirror of the entrance — a spring exit loses its bounce entirely. An entrance introduces something; an exit removes something the user has already finished with, and lingering reads as lag.
3. **Reach for a purpose, not a raw duration.** The purpose aliases above say what a motion is for; the durations say only how long it is.
4. **Duration should grow with travel distance, sub-linearly.** Roughly `duration x (travel / 160px)^0.5`, clamped to 0.6x-1.8x. Apply it to motions that actually travel; a checkbox filling has no distance.
5. **Stagger falls off.** Each motion carries its own per-child offset — subtle 40ms, standard 40ms, emphasized 40ms — applied as `offset x index^0.85`, so a long list doesn't take proportionally long.
6. **Always ship the `prefers-reduced-motion` block.** It's in the CSS export already. In Framer Motion use `<MotionConfig reducedMotion="user">`.
## A spring has no duration
It approaches its target asymptotically and never arrives. Any duration you see for a spring is a *settling threshold* — the point at which the runtime decides it's close enough. Different runtimes pick differently, so the same spring honestly reports different durations on different platforms. The numbers above use Framer Motion's convention.
## Porting to platforms this tool doesn't export
Only `k/m` and `c/m` affect the motion, so normalising mass to 1 is lossless — not an approximation.
- **SwiftUI**: `response = 2π·√(m/k)`, `dampingFraction = c / (2·√(k·m))`. Beziers map to `.timingCurve(x1, y1, x2, y2, duration:)`.
- **Compose**: `stiffness = k/m`, `dampingRatio = c / (2·√(k·m))` — mass is fixed at 1 there, which the normalisation above makes exact. Beziers map to `CubicBezierEasing(x1, y1, x2, y2)`.
## Changing this set
Every parameter is optional; with none you get the default set.
```
e Repeated once per motion, six fields separated by "*":
id*name*easing*durationMs*exit*staggerMs
easing is one of
b.<x1>.<y1>.<x2>.<y2> cubic-bezier, all four values x100,
so cubic-bezier(0.2,0,0,1) is b.20.0.0.100
s.<stiff>.<damp>.<mass>.<velocity>
stiffness and damping as-is; mass and
velocity x100, so mass 1 is written 100
exit is r<percent> (a share of the entrance) or a<ms> (absolute)
pu One value: the entry id for each purpose in order, joined by "."
state, dropdown, tooltip, list, drawer, modal, toast
xt Tokens held out of the export: <entryId>*<enter|exit>, "." between
tol Spring sampling tolerance, ten-thousandths, 1-2000. Default 100 (1%).
```
Full contract: https://www.springs.studio/llms.txt
## Getting the code
The ready-made CSS, Tailwind theme, Framer Motion transitions and DTCG file are not in this text. They are in the JSON at https://www.springs.studio/api/tokens, which takes the same query string as this page. If you are reading this as markdown, that JSON was stripped along with the script tag holding it — fetch the URL rather than rebuilding the stylesheet from the table above.
## Other tools in this family
Studio Tools — Small, free, agent-readable design utilities. No account, no API key, nothing stored.
```
Ramps Color scales & semantic tokens https://www.ramps.studio/
Perceptually-even OKLCH scales and accessible tokens from one brand color.
Springs Motion, easings & durations https://www.springs.studio/ (this tool)
Easing curves, springs and durations you can preview on real UI.
Beeps UI sounds & feedback https://www.beeps.studio/
A coherent set of interface sounds, synthesized rather than sampled.
Depths Elevation & shadows not yet released
Elevation levels and a shadow ramp derived from one light source.
Texts Type styles & scaling not yet released
Scales that interpolate with the viewport, and the text styles built on them.
SVGs Icon cleanup & alignment not yet released
Clean up exported SVGs and sit them on a consistent optical grid.
```