# Design Guide — Motion & Material

The canon for how Execution Space moves and feels in the digital space. Pairs with the live
guide at [`design/index.html`](index.html) (every principle below is demonstrated there) and
with [`INTERFACE-GUIDE.md`](INTERFACE-GUIDE.md) (components/UX) and
[`CONTENT-DESIGN.md`](CONTENT-DESIGN.md) (editorial).

**Files in this system**

| File | Role |
|---|---|
| `es-motion.css` | Motion tokens + keyframe library (import after `es-tokens.css`) |
| `es-animatics.js` | `<es-animatic>` web component + easter-egg engine |
| `index.html` | The live, interactive guide (eggs armed) |
| `../_components/es-tokens.css` | Color/type/spacing tokens — the base layer |
| `../_components/es-stars.js` | Star-field material injector |

---

## 1 · Motion principles

The brand voice is **direct, embedded, outcome-led** — motion has to speak the same way.

1. **Enter with purpose.** Motion always travels toward its resting place. Nothing wanders,
   orbits, or bounces idly. If an element moves, it's *arriving*.
2. **Settle fast.** Short attacks, long tails — `--eout` for travel, `--espring` when a mark
   deserves one overshoot. The eye should never wait for the interface.
3. **Earn the loop.** Ambient motion (twinkle, breathe, scan) stays sub-perceptual. The moment
   a loop draws the eye, it must be carrying meaning (loading, thinking, live).
4. **Respect the visitor.** Every animation collapses to its resting state under
   `prefers-reduced-motion: reduce`. Easter eggs never arm. This is non-negotiable.

### Duration scale (`es-motion.css`)

| Token | Value | Use |
|---|---|---|
| `--t-instant` | 90ms | state flips: hover fills, toggles |
| `--t-quick` | 180ms | micro-interactions: buttons, links |
| `--t-move` | 320ms | element travel: cards, panels |
| `--t-reveal` | 700ms | scroll reveals, section entrances |
| `--t-build` | 1100ms | hero builds, mark assembly |
| `--t-ambient` | 6s | background loops |

### Easing

| Token | Curve | Character |
|---|---|---|
| `--eout` | `.16,1,.3,1` | the house easing — decisive arrival |
| `--espring` | `.34,1.56,.64,1` | one overshoot, then still — marks & badges |
| `--ease` | `.25,.46,.45,.94` | soft accents (underlines) |
| `--e-flat` | `.4,0,.6,1` | ambient loops |
| `--e-in` | `.55,0,1,.45` | exits only |

**Rule:** durations and easings come from tokens, never hand-typed values.

---

## 2 · Animatics

Lottie-style, dependency-free vector loops: inline SVG driven by CSS, shipped as a web
component. No player library, no JSON payloads, no network requests.

```html
<script src="../design/es-animatics.js"></script>
<es-animatic name="mark-assemble" loop></es-animatic>
```

Attributes: `name` (registry key) · `size` (px, default 160) · `loop` (idle-breathe after
build, where supported) · `still` (resting frame, no motion — applied automatically under
reduced motion).

### Registry

| Name | Motion | Where it belongs |
|---|---|---|
| `mark-assemble` | nine diamonds spring in, settle, breathe | hero moments, page loads, loaders |
| `transform-morph` | square → diamond → X, continuous | "transforms." motif — About, brand moments |
| `constellation` | dots connect, lines draw, twinkle | ambient backdrop for dark sections |
| `rocket-trail` | rocket arcs with dash trail | 404/500, footers, send-offs (Little Rocket nod) |
| `exe-cursor` | types `ecom.exe`, block caret blinks | terminal idiom — dev/capability contexts |
| `pulse-grid` | radial pulse through the 44px dot lattice | loading, "working", background texture |
| `chip-energize` | mark ignites, energy ripples outward through a cell grid | filed away, 2026-07-17 — not yet placed. Concept: "embedded, and it lights up the whole system" (Ada). Built to replace an earlier GIF version of the same idea (`hero-embedded-lights-on.gif`) that couldn't respect reduced-motion or the shared yellow token. |

**Adding an animatic:** extend `REGISTRY` in `es-animatics.js` (a builder returning an
`<svg>`), style it in the injected stylesheet, add a reduced-motion still state, then add a
demo card to `index.html` and a row here. Brand yellow is the `YELLOW` const — one place.

---

## 3 · Materials

Named surface treatments. Use them by recipe — don't improvise new textures per page.

| Material | Recipe | Feels like |
|---|---|---|
| **grain** | fractalNoise SVG data-URI, `opacity .022`, fixed overlay (in `es-tokens.css`) | print, physicality |
| **dot-grid** | `radial-gradient(rgba(255,205,5,.05) 1px, transparent 1px)` / `44px 44px` | engineering paper |
| **mesh** | 2 radial ellipses of accent at 4–14% over `#141616` | depth without photography |
| **stars** | `es-stars.js` — 2px twinkles, ~10% accent-colored | the Little Rocket sky |
| **scanline** | `m-scan` gradient sweep, accent at ≤35% | terminal, liveness |
| **brand yellow** | `--accent` `#FFCD05` flood + `.ycta-corners` brackets | the signature |

Rules: dark surfaces carry the texture; yellow surfaces stay clean (corners bracket motif
only). Never stack more than two materials. Grain sits above everything at 2% — it's felt,
not seen.

> **Canon note:** brand yellow is `#FFCD05` per `content/CONTENT-GUIDE.md`. ES-103 tracks a
> competing `#FFC800` — if that lands, change `--accent` (tokens) and `YELLOW`
> (es-animatics.js) and everything follows.

---

## 4 · Easter eggs

Small rewards for the ones who look closer. Arm per page with `ESAnimatics.eggs()`
(optionally a subset: `ESAnimatics.eggs(['rocket','token'])`).

| Egg | Trigger | Payoff |
|---|---|---|
| `rocket` | 5 rapid clicks on the logo / any `[data-egg-logo]` | rocket crosses the viewport |
| `exe` | typing `exe` outside form fields | yellow scanline sweep |
| `konami` | ↑↑↓↓←→←→BA | hyperspace starfield warp |
| `token` | press-and-hold 800ms on any `[data-egg-token]` surface | design-token chip reveal |

### House rules for eggs

- **Silent.** No audio, ever.
- **Brief.** Payoffs complete in under 2 seconds and clean up after themselves.
- **Harmless.** Overlay layer is `pointer-events: none`; nothing blocks or navigates.
- **Discoverable, not advertised.** One wink allowed per page (e.g. a `title` attribute).
- **Off under reduced motion.** The engine checks and refuses to arm.
- **Production restraint:** ship at most `rocket` + `token` on executionspace.com; the full
  set lives on the creative hub and the design guide.

---

## 5 · Where this expands the brand

The static identity (Figtree, yellow, dark, diamonds) already reads *considered*. The motion
layer adds the missing register: **precision in time**. Assembly (mark-assemble) says we
build; morphing (transform-morph) says we transform; constellation says we connect; the
terminal caret says we ship code. Every animatic is an argument, not an ornament — that's
what keeps "go wild" on-brand.
