# Motion

> Short and calm. Three durations, two curves, no springs, no spinner. Motion explains what happens and stands still when the system asks for less motion.

Source: https://brand.heyalbert.family/en/bewegung/ · Hey Albert brand and design system

Motion explains; it does not decorate. A card glides to where it now belongs. A toast comes up from below. A skeleton breathes until the content arrives. Nothing else moves.

## Durations and curves

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| dauer-kurz | var(--dauer-kurz) | 120ms |  |  |
| dauer-mittel | var(--dauer-mittel) | 200ms |  |  |
| dauer-atem | var(--dauer-atem) | 300ms |  |  |
| verlauf-ruhig | var(--verlauf-ruhig) | cubic-bezier(0.2, 0, 0.2, 1) |  |  |
| verlauf-atem | var(--verlauf-atem) | cubic-bezier(0.4, 0, 0.6, 1) |  |  |
| dauer-kurz | var(--dauer-kurz) | 0ms |  |  |
| dauer-mittel | var(--dauer-mittel) | 0ms |  |  |
| dauer-atem | var(--dauer-atem) | 0ms |  |  |

| Token | For |
|---|---|
| `--dauer-kurz` | states: hover, press, focus, a colour change |
| `--dauer-mittel` | reveals: menu, toast, dialog |
| `--dauer-atem` | the skeleton’s breath |
| `--verlauf-ruhig` | everything except the breath |
| `--verlauf-atem` | only the skeleton, back and forth |

In SwiftUI: `AlbertBewegung.verlaufRuhig(AlbertBewegung.dauerKurz)`.

## What moves

- **States** change softly: background, outline, text colour. Never the size.
- **Reveals** arrive calmly; a toast rises a few pixels from below.
- **One thing travels:** when Tobias takes the drive, the card glides from “open” into his lane. On the website exactly this one movement shows what Albert does.
- **The skeleton breathes** between `--karte` and `--knopf-zweit`. It has the shape of the content that is about to arrive.

## What never moves

- No springs, no bouncing, no wobbling.
- No spinner. Whoever waits sees a skeleton.
- No progress bar as decoration.
- No confetti, not even when Lena has ticked everything off. Albert states (“Fertig.” – done); praise comes from people.
- No autoplay video and no carousel on the website.

### Skelett

Source: `packages/design-system/components/zustaende/Skelett.jsx`

Das Skelett – die Form dessen, was gleich kommt.

```jsx
<Skelett form="board" spalten={7} zeilen={3} />
```

Nie ein Kreisel, nie ein Fortschrittsbalken. Es atmet zwischen Karte und Zweitknopf-Beige und steht still, wenn das System weniger Bewegung will.

```ts
/** Skelett in der Form des Inhalts. Atmet 300 ms, steht bei reduzierter Bewegung, nie ein Kreisel. */
export interface SkelettProps {
  /** "karte" (eine Karte) | "zeile" (Liste) | "board" (Stundenraster). */
  form?: "karte" | "zeile" | "board";
  /** Zeilen je Spalte. */
  zeilen?: number;
  /** Spalten im Board. */
  spalten?: number;
  style?: React.CSSProperties;
}
export function Skelett(props: SkelettProps): JSX.Element;
```

## Reduced motion

Whoever has asked their system for less motion gets none. With `prefers-reduced-motion: reduce` all three durations are zero. The skeleton stops breathing; the toast simply appears.

#### Motion · Dauern

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| dauer-kurz | var(--dauer-kurz) | 120ms |  |  |
| dauer-mittel | var(--dauer-mittel) | 200ms |  |  |
| dauer-atem | var(--dauer-atem) | 300ms |  |  |

#### Motion · Verläufe

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| verlauf-ruhig | var(--verlauf-ruhig) | cubic-bezier(0.2, 0, 0.2, 1) |  |  |
| verlauf-atem | var(--verlauf-atem) | cubic-bezier(0.4, 0, 0.6, 1) |  |  |

#### Motion · Reduzierte Bewegung

| Token | CSS | Value | Dark | Meaning |
| --- | --- | --- | --- | --- |
| dauer-kurz | var(--dauer-kurz) | 0ms |  |  |
| dauer-mittel | var(--dauer-mittel) | 0ms |  |  |
| dauer-atem | var(--dauer-atem) | 0ms |  |  |

In SwiftUI `accessibilityReduceMotion` switches motion off completely, not halfway.

## In short

> **Do**
>
> - Only the three durations and the two curves.
> - Motion that shows where something went.
> - Skeleton instead of spinner.

> **Don't**
>
> - Spring curves, `spring()`, custom curves, durations above `--dauer-atem` for states.
> - Animation as a reward or to grab attention.
> - Motion that keeps running under reduced motion.
