# Intents

> The catalog of motion intents — what each moment means, and how interanimate resolves it by default.

An **intent** declares what a moment *means*. interanimate resolves the intent into purpose, channels, motion type, tokens, choreography, and reduced-motion behavior. Intents are the front door of the framework: most product code should only ever name intents.

## Why intents [#why-intents]

Motion values ("300 ms ease-out, translate 8 px") describe *how*. They don't carry *why*, so they can't adapt. An intent carries the why, which lets the framework make every other decision consistently — including ones the author never thought about, like what to do under reduced motion or when a person grabs the element mid-flight.

Intents also give teams a shared vocabulary. "This should be a `reveal` from the avatar" is a design review comment that both designers and engineers can act on.

## Anatomy of an intent [#anatomy-of-an-intent]

Every intent defines:

| Field | Meaning |
|---|---|
| **Purpose** | One of feedback, orientation, state, attention, delight (Principle 2) |
| **Channels** | Which spatial and effect channels it typically drives |
| **Motion** | Default motion type per channel |
| **Tempo / character** | Default [tokens](/docs/tokens) |
| **Frequency** | Default frequency tier, which caps tempo and character |
| **Choreography** | Origin requirements, pairing, ordering |
| **Interruption** | What happens if a person interacts mid-flight |
| **Reduced** | The required reduced-motion substitution |

## The catalog [#the-catalog]

v0 defines ten intents. They are grouped by purpose.

### Feedback [#feedback]

#### `acknowledge` [#acknowledge]
The interface heard the person — a button press, a toggle, a selection.

- **Channels:** scale (spatial, subtle), highlight (effect)
- **Motion:** spring, `swift`, `smooth`
- **Frequency:** `frequent`
- **Choreography:** none; local to the element
- **Notes:** Resolves on input start. A pressed control shrinks only slightly (Kowalski's guidance is around 0.97 of full size); release may be a touch slower than press so a quick tap is still perceptible.
- **Reduced:** highlight only; no scale.

#### `follow` [#follow]
Values track a person's input directly — dragging, scrubbing, resizing.

- **Channels:** position, size, progress (spatial)
- **Motion:** none while tracking (1:1); hands off to `release`
- **Frequency:** inherits from context
- **Notes:** Governed entirely by the [interaction model](/docs/interaction-model).
- **Reduced:** unchanged. This motion is controlled by the person and is essential.

#### `release` [#release]
A direct manipulation ended; carry the value to rest.

- **Channels:** whatever `follow` drove
- **Motion:** spring inheriting release velocity; projection chooses the target
- **Character:** `smooth` by default; `lively` permitted because momentum was supplied
- **Reduced:** projection still chooses the outcome; the motion becomes a short effect transition (fade or instant placement), never a throw.

### Orientation [#orientation]

#### `reveal` [#reveal]
Something appears: a popover, menu, tooltip, dialog, toast, expanding section.

- **Channels:** opacity (effect) + small scale or translation (spatial)
- **Motion:** spring for spatial, tween (enter) for effect
- **Tempo:** `quick` for small surfaces, `standard` for dialogs, `relaxed` for large sheets
- **Frequency:** `occasional`
- **Choreography:** **requires an origin** — the element or edge it comes from. Popovers and menus grow from their trigger; toasts and sheets come from their edge. Dialogs centered on screen may use the viewport center. Never enters from nothing: scaling up from zero size is disallowed; entering scale starts close to full size.
- **Reduced:** opacity only.

#### `conceal` [#conceal]
Something disappears. The inverse of `reveal`.

- **Motion/channels:** mirror the matching `reveal`
- **Tempo:** one step faster than the matching `reveal`
- **Choreography:** returns toward the same origin it came from
- **Interruption:** if `reveal` is triggered during `conceal`, it reverses from the current value — no restart
- **Reduced:** opacity only, shorter.

#### `navigate` [#navigate]
The view changes — moving between pages, tabs, steps, or levels of hierarchy.

- **Channels:** position or shared-element transform (spatial) + crossfade (effect)
- **Motion:** spring for spatial; tween for crossfade
- **Tempo:** `standard`
- **Frequency:** depends on context; core navigation is `frequent` or `constant`, which reduces it to a near-instant crossfade or nothing
- **Choreography:** carries **direction** — forward, back, up, down, lateral. Forward and back are spatial mirrors. Elements that persist across both views may morph between positions (shared-element continuity).
- **Reduced:** crossfade only. No full-screen movement — large-area motion is a known vestibular trigger.

#### `relocate` [#relocate]
Something moves to a new position within the same view: reordering, layout shifts, items inserted or removed from a list.

- **Channels:** position, size (spatial)
- **Motion:** spring, `standard`, `smooth`
- **Frequency:** `occasional` (but rapid repeats retarget rather than queue)
- **Choreography:** neighbors move together; removed items leave before others close the gap; inserted items make room before arriving
- **Reduced:** instant layout change with a brief highlight on what moved, so the change is still legible.

### State [#state]

#### `morph` [#morph]
An element changes form while remaining the same thing: a button becoming a progress indicator, a card expanding into a detail view, a toggle sliding.

- **Channels:** size, shape, position (spatial) + content crossfade (effect)
- **Motion:** spring, `standard`
- **Notes:** The element's identity is continuous — this is the key difference from `conceal` + `reveal`.
- **Reduced:** crossfade between forms in place.

#### `indicate` [#indicate]
Ongoing status: loading, progress, syncing.

- **Channels:** progress (spatial or effect), opacity
- **Motion:** linear tween for progress tied to real work; for indeterminate status, a gentle, low-contrast loop
- **Frequency:** as needed; never decorative
- **Notes:** Determinate progress should reflect real progress. Indeterminate indicators that keep running beyond a few seconds should settle into a calmer state or switch to an explicit status message, in the spirit of WCAG 2.2.2 (Pause, Stop, Hide).
- **Reduced:** static or slowly pulsing indicator; no spinning.

### Attention [#attention]

#### `emphasize` [#emphasize]
Draw the eye to something that needs it: a validation error, a newly arrived item, a required action.

- **Channels:** effect (color, highlight) first; small spatial motion only if effect alone is insufficient
- **Motion:** brief, non-looping
- **Frequency:** `occasional`; **must not repeat** automatically
- **Notes:** Attention is a scarce resource. One emphasized thing per view at a time.
- **Reduced:** color or highlight only. Never shake.

### Delight [#delight]

#### `celebrate` [#celebrate]
A rare, high-emotion moment: completing onboarding, a first success, a milestone.

- **Channels:** any
- **Motion:** any; this is the only intent where `bouncy` character and `deliberate` tempo are allowed by default
- **Frequency:** `rare` — this is enforced, not suggested
- **Notes:** Never blocks the person from continuing. Never conveys required information.
- **Reduced:** a static illustration or a simple fade. Flashing content must stay below three flashes per second (WCAG 2.3.1) in all modes.

## Intent summary *(informative)* [#intent-summary-informative]

| Intent | Purpose | Default tempo | Default character | Frequency | Reduced |
|---|---|---|---|---|---|
| `acknowledge` | Feedback | swift | smooth | frequent | Highlight only |
| `follow` | Feedback | — (1:1) | — | context | Unchanged |
| `release` | Feedback | from velocity | smooth → lively | context | Short effect |
| `reveal` | Orientation | quick–relaxed | smooth | occasional | Fade |
| `conceal` | Orientation | one step faster | smooth | occasional | Shorter fade |
| `navigate` | Orientation | standard | smooth | varies | Crossfade |
| `relocate` | Orientation | standard | smooth | occasional | Instant + highlight |
| `morph` | State | standard | smooth | occasional | Crossfade |
| `indicate` | State | linear / loop | flat | as needed | Static / pulse |
| `emphasize` | Attention | quick | smooth | occasional, no repeat | Color only |
| `celebrate` | Delight | up to deliberate | up to bouncy | rare | Static / fade |

## Custom intents [#custom-intents]

Teams can define their own intents by composing the same fields. A custom intent must declare a purpose, a frequency, and a reduced behavior — the framework refuses to resolve one that doesn't. This is how interanimate stays general-purpose without giving up its principles.
