# MOTION_GUIDELINES.md

## 1. Motion philosophy

**"Motion confirms; it never performs."** Every animation must answer a user question — *did my click register? what changed? where did this come from?* — or it doesn't ship. One exception: the hero trace draw, the site's single identity moment.

This is the strongest anti-junior signal available: restraint executed perfectly.

## 2. Tokens

| Token | Duration | Easing | Use |
|---|---|---|---|
| `instant` | 80ms | linear | Colour/opacity on hover |
| `quick` | 160ms | ease-out (0.2, 0, 0, 1) | Buttons, chips, toggles, focus |
| `standard` | 240ms | ease-out | Card hover lift, menu open, theme cross-fade |
| `entrance` | 400ms | ease-out, slight overshoot-free | Section reveals (opacity + 12px rise) |
| `signature` | 700ms | ease-in-out | Hero trace draw only, once per page load |

Rules: nothing exceeds 700ms; entrances stagger max 3 items × 60ms; **only `transform` and `opacity` animate** (performance budget — no layout/box-shadow/filter animation); parallax capped at 4px (project-card screenshots).

## 3. Reduced motion (first-class variant, not an off-switch)

`prefers-reduced-motion: reduce` →
- Entrances become pure opacity fades (120ms), no translation.
- Trace motif renders complete, static.
- Theme switch: instant swap.
- Status-dot pulse: static dot.
- Scroll behaviour: instant anchor jumps, no smooth scroll.
Nothing is *removed* — content parity is exact.

## 4. Loading states

| Context | Design |
|---|---|
| Initial page | No spinner, no splash: text renders immediately (fonts swap-safe), hero trace draws as the "loaded" confirmation. Perceived performance *is* the loading design. |
| Screenshots / gallery | Aspect-ratio-locked skeleton: `surface-2` block + faint dot-grid + mono caption already visible (`loading capture…` / `laster skjermbilde…`); cross-fade 240ms on load. Zero layout shift, ever. |
| Form submit | Button label → inline three-dot mono ellipsis animation (·, ··, ···), button stays same width; success swaps band to confirmation panel (see MICRO_INTERACTIONS §form). |
| Language switch | Content cross-fade 160ms; header/footer chrome does not blink (only text nodes swap). |
| Lightbox open | Backdrop fade 240ms + image scale 0.98→1. |

## 5. Page & theme transitions

- Route changes: outgoing fade 120ms → incoming rise-fade 240ms, header persistent. No full-screen wipes.
- Theme toggle: 240ms token cross-fade; the toggle icon morphs (sun⇄moon path) in `quick`. Screenshots swap themed variants where available (JobTrack/InboxIntel both have dark UIs — capture both if the apps support it, else keep one honest capture).

## 6. Scroll-linked motion (summary — full spec in SCROLL_EXPERIENCE.md)

- Section reveals trigger at 20% viewport entry, once (no re-trigger on scroll-up).
- Header compresses 72→56px between 0–120px scroll, linear-mapped.
- No scroll-jacking, no pinned scenes, no horizontal hijack — recruiters skim; the scrollbar must behave like a document's.
