# Tokens

> Tempo, character, and frequency — the shared scales that describe how motion feels in interanimate.

Tokens are named, shared scales that describe how motion **feels**. They let a team say "make it `quick` and `smooth`" instead of debating milliseconds and stiffness, and they let the framework adapt a decision consistently across springs, tweens, and platform-native mechanisms.

interanimate has three token scales. **Tempo** and **character** describe a motion. **Frequency** describes how often a person meets it, and caps the other two.

<Callout title="v0 defaults">
  All values on this page are **v0 defaults**. They are calibrated against the sources cited, but they are expected to be tuned against real prototypes before v1. The *scale structure* is normative; the exact numbers are not yet.
</Callout>

## Tempo [#tempo]

How long a motion **feels**. For springs this is perceptual duration; for tweens it is literal duration.

| Token | Feels like | v0 value | Typical use |
|---|---|---|---|
| `instant` | No motion | 0 | Keyboard actions, `constant`-frequency actions, reduced fallbacks where any motion is unhelpful |
| `swift` | Barely there | ~120 ms | Press feedback, toggles, highlights |
| `quick` | Crisp | ~180 ms | Tooltips, small popovers, dropdowns |
| `standard` | Default UI motion | ~260 ms | Most reveals, morphs, relocations, navigation |
| `relaxed` | Unhurried | ~400 ms | Large surfaces: drawers, sheets, full-panel changes |
| `deliberate` | Noticeable, intentional | ~600 ms | Rare, expressive moments only |

**Why these values.** Kowalski's budgets place press feedback around 100–160 ms, tooltips and small popovers around 125–200 ms, dropdowns around 150–250 ms, and modals and drawers anywhere from 200–500 ms, with standard UI under 300 ms. IBM Carbon's productive durations sit in the same short range and its expressive durations run longer. The tempo scale sits inside those envelopes, with `deliberate` reserved for the expressive tier.

### Tempo rules *(normative)* [#tempo-rules-normative]

1. **Exits are faster.** A `conceal` resolves one step below its matching `reveal`.
2. **Distance is sub-linear.** When travel distance is known, tempo may step up for large travel, but no more than one step, and never past `relaxed` outside the `rare` tier. Large movements need a little more time to read; they don't need proportionally more.
3. **Keyboard is instant.** Keyboard-initiated actions resolve to `instant`. People reach for the keyboard to go fast; motion makes those actions feel delayed. An author can override this per intent, visibly, for rare cases.
4. **Under reduced motion**, effect substitutions use `swift` or `quick`.

## Character [#character]

How much a motion **overshoots**. Character only applies to springs; tweens are always `flat` or `smooth` by their curve.

| Token | Feels like | v0 bounce | Allowed when |
|---|---|---|---|
| `flat` | Settles slowly, no overshoot | slightly negative (overdamped) | Calm, heavy surfaces; background changes |
| `smooth` | Settles cleanly, no overshoot | 0 (critically damped) | **Default for everything** |
| `lively` | A small, natural overshoot | ~0.15 | Momentum was handed off by a gesture, or tier is `rare` |
| `bouncy` | A clear, playful overshoot | ~0.3 | Tier is `rare` only |

**Why these values.** Apple's spring guidance is the calibration: around 0.15 bounce barely reads as bouncy, around 0.3 is noticeably bouncy, and values beyond roughly 0.4 tend to feel exaggerated for interface elements. Apple also recommends zero bounce when in doubt. interanimate's scale stops at `bouncy` deliberately — there is no token beyond it.

### Character rules *(normative)* [#character-rules-normative]

1. Default character is `smooth`.
2. `lively` requires either momentum hand-off (the person supplied velocity) or the `rare` tier.
3. `bouncy` requires the `rare` tier.
4. Effect channels never bounce. An opacity that overshoots is a flicker.
5. Under reduced motion, all character resolves to `smooth` or `flat`.

## Frequency [#frequency]

How often a person will **encounter** a motion. Frequency is the budget that keeps an interface from becoming tiring. It caps tempo and character; it never raises them.

| Token | Encountered | Max tempo | Max character | Examples |
|---|---|---|---|---|
| `constant` | Hundreds of times a day | `instant` | — | Command palettes, keyboard shortcuts, core navigation |
| `frequent` | Tens of times a day | `swift` | `smooth` | Hover states, list navigation, toggles, press feedback |
| `occasional` | A few times a session | `relaxed` | `lively`* | Modals, drawers, toasts, settings panels |
| `rare` | Once, or on milestones | `deliberate` | `bouncy` | Onboarding, empty states, success and celebration |

\* `lively` in the `occasional` tier only via momentum hand-off.

**Why these tiers.** They follow Kowalski's frequency gate closely: actions seen a hundred or more times a day get no animation at all, those seen tens of times a day get at most near-imperceptible motion, occasional surfaces get standard animation, and rare or first-time moments are where expressive motion belongs. They also echo IBM Carbon's split — productive motion for task-focused moments, expressive motion reserved for occasional, significant ones.

### Frequency rules *(normative)* [#frequency-rules-normative]

1. Every intent has a default frequency tier.
2. An author may declare a different tier when the context differs (a settings panel opened once a month is `rare`; a toast in a chat app may be `frequent`).
3. Exceeding a tier's caps requires an explicit override that is visible in review — it is never silent.

## Resolution example *(informative)* [#resolution-example-informative]

A `reveal` of a dropdown menu:

- Intent default: tempo `quick`, character `smooth`, frequency `occasional`.
- Author: no override.
- Frequency cap: `occasional` allows `quick` and `smooth`. ✓
- Environment: fine pointer, good headroom. ✓
- Preference: reduced motion **on** → spatial channel dropped; opacity tween at `swift`.

Result: the menu fades in quickly from its trigger with no movement.

The same menu opened by keyboard with reduced motion **off**: the keyboard rule resolves tempo to `instant`. Result: it appears immediately. Opened by mouse a moment later, it animates again — resolution happens per occurrence, from the input that caused it.
