Patterns
Components are parts. A pattern is what they do together when something happens. Ten flows, each running live on the real components, with the language from 21 and the motion from 10.
What happens, in order.
Every flow reads the same way: the trigger, what moves, how long, what Milo says. Press Play to watch it at real speed; open Spec for the step table.
Empty → first item
An empty surface is calm, not apologetic. Quick Entry is the shortest route in; the first row arrives with emerge.
Nothing here. Suspiciously peaceful.
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Surface loads with no tasks | Nothing. The statement holds the space. | — | Nothing here. Suspiciously peaceful. | .empty (display serif) |
| ⌘K | Quick Entry appears at Level 3 | fast · enter | What do you intend? | .quick-entry |
| ↩ | Quick Entry dismisses; row emerges from where it will live | fast · exit → slow · enter | On it. “…” is now a task. | .rows .row · .toast.by-milo |
| Row lands | State glyph settles to queued | base · standard | Queued | .state-queued |
Task → Run → Artifact
The row is the origin. A run drops out of it, steps complete in place, the artifact emerges, and the row folds back with a result.
Recut the Day 4 opener to the founder trackQueued
- Load founder track—
- Align title cards—
- Render 1080p proof—
local · James MacBook Pro
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Start | Row state queued → running; glyph pulses | base · standard | On it. | .state-active |
| Run opens | Run detail expands from the row (height + opacity) | base · standard (expand) | — | .disclosure[open] .run-detail |
| Each step | Glyph ○ → ● → ✓; the left rule lights on the active step | base · standard | step names, durations in mono | .steps li.on / .done |
| Last step done | Artifact emerges below the steps | slow · enter (emerge) | filename + path | .artifact |
| Complete | Row folds back; state done; toast | fast · exit (collapse) | Done. Three files changed. | .state-done · .toast |
Ask → Allow → Running
Milo asks before spend, before writing outside the project, before anything destructive. The ask is Level 3, one line long, and names the cost.
Do the same for Days 5 to 12.
Eight files. This needs your approval before I run ffmpeg on them.
- Recut Days 5–12Running
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Milo reaches a gated action | Milo turn appears | slow · enter | This needs your approval. | .turn.milo |
| Ask | Permission surface rises at Level 3, vermilion left edge; focus moves to it | fast · enter | Run ffmpeg on 8 files? Where · Executor · Cost | .permission (level 3) |
| Allow once | Ask dismisses; row appears running | fast · exit → base · standard | Allowed once. Running locally. | .row.is-active · .toast |
| Deny | Ask dismisses; nothing else changes | fast · exit | Left as it was. | — |
Spend authorisation and destructive actions use .confirmation at Level 4 with a scrim; the flow is the same with one more step of friction.
Error → Recover
An error says what stayed unchanged. Recovery is one control, in place. Nothing turns red except the state.
- Publish FAM print proofRunning
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Executor fails | State running → failed (✕ + label); Retry appears in the trail | base · standard | That didn't work. Here's what stayed unchanged: nothing was published. | .state-error · .btn-s |
| Retry | State → running; message clears | base · standard | Trying again. | .state-active |
| Success | State → done | base · standard | Done. Proof is live. | .state-done |
Colour is never the only signal: the glyph changes (● → ✕ → ✓) and the label changes with it.
Undo
Completing or deferring never confirms first. It happens, a toast offers Undo for five seconds, and undo puts the row back exactly where it was.
- Reply to the FAM print proofQueued
- Approve Euangelion render batch 7Needs you
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Not now / complete | Row collapses out of the list | fast · exit (collapse) | — | .row |
| Immediately | Toast rises with Undo; five-second window | fast · enter | Moved to tomorrow. / Done. | .toast + Undo |
| Undo | Row emerges in its original position; toast dismisses | slow · enter (emerge) | Back where it was. | .row.emerge-in |
| Window ends | Toast dismisses; history keeps the action | fast · exit | — | Activity |
Pause / Resume
Pausing loses nothing. The state says Paused with its own glyph, the control flips to Resume, and progress holds where it stopped.
- Render Euangelion batch 8Running
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Pause | State ● Running → ‖ Paused; progress bar holds; button reads Resume | base · standard | Paused. Nothing lost. | .state-paused · .progress |
| Resume | State → Running; bar continues from the same point | base · standard | Resumed. | .state-active |
Implemented by [data-pause-task] in site.js: it toggles classes and copy; production wires the same contract to the run engine.
Voice ↔ Quick Entry
Same intent, two doors. Voice is the pill at the top; Quick Entry is ⌘K. Both end in the same row, with the same words.
Voice
⌥ Space
Keyboard
⌘K
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| ⌥ Space | Pill appears top-centre (scale 0.96 → 1) | fast · enter (voice-appear) | Listening | .voice-pill[data-state=listening] |
| Speech ends | Ring dashes and rotates; then dot pulses | base · standard (voice-resolve) | Understanding → Working | [data-state=understanding|working] |
| Done | Check; holds 900ms; dismisses | fast · exit (voice-dismiss) | Done. | [data-state=done] |
| ⌘K | Quick Entry rises at Level 3; ↩ creates; esc closes | fast · enter / exit | On it. “…” is now a task. | .quick-entry |
| Either | Same row emerges in Today | slow · enter (emerge) | identical row text | .row |
Summarized → tucked → revealed → expanded
Today shows one statement and two rows. "3 more" is tucked. Reveal it; then expand one row into its run. Four levels, one surface, nothing hidden for good.
What matters now
Cut the Daily Bread Day 4 opener.
- Reply to the FAM print proofQueued
- Approve Euangelion render batch 7Needs you
3 more todaytucked
- Order archival cream stockIdle
- Render Euangelion batch 8Running
- Load plates4s
- Render 12 frames2m 14s
- Assemble proof—
- Write the Thursday noteIdle
Spec
| Level | What is visible | Trigger | Duration · easing | Components |
|---|---|---|---|---|
| Summarized | One statement, the primary action, two rows | surface loads | — | .today-statement · .row |
| Tucked | "3 more today" with the word tucked | — | — | .disclosure > summary |
| Revealed | The three rows, in place, below the two | click / ↩ on the summary | base · standard (expand) | .disclosure[open] |
| Expanded | One row's run: steps, executor, artifacts | click / ↩ on the row | base · standard (expand) | .run-detail .steps |
The same ladder structures this documentation: each section is a statement, a summary line, and a tucked spec. Information appears because it is relevant, not because it exists.
Vermilion entering Moss
Offline is healthy on its own, in Moss. When Milo starts acting inside it, Vermilion enters the field: a presence line, a ◉ beside the machine, a running state. When Milo stops, the Moss remains.
◉ Milo is rendering Euangelion batch 8 on James MacBook Pro · 0 of 12
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Milo starts a run on a machine | Presence line emerges inside the Moss field with a vermilion left edge; the machine's glyph gains ◉ | slow · enter (emerge) | ◉ Milo is rendering … on … | .offline-field .milo-presence · .machine.has-milo |
| Working | Count advances; load reads in mono | base · standard | 3 of 12 | .mono-micro |
| Milo finishes | Presence collapses; ◉ leaves; the field stays Moss | fast · exit (collapse) | Done. Finished in 2m 14s. | .toast.by-milo |
Vermilion is never used to mean "healthy" and Moss is never used to mean "Milo". Each colour keeps its owner; the flow is the two meeting.
Theme + reduced motion
Dark is a second token set, not an inversion: colours crossfade, imagery remaps to Nous, Vermilion lifts for contrast. Under reduced motion the same surface changes without moving.
- Reprint the series artRunning

This browser: checking…
Spec
| Trigger | What moves | Duration · easing | Copy | Components |
|---|---|---|---|---|
| Dark | Semantic tokens switch on [data-theme=dark]; background and text crossfade; image swaps to the Nous derivative | slow · standard (theme-switch) | — | tokens/milo.css · .theme-scope |
| Light | Reverse; image returns to National Park | slow · standard | — | — |
| Reduced motion | All --dur-* collapse to ≤120ms; ambient off; dither draws its final frame; state pulses stop | — | — | @media (prefers-reduced-motion) in tokens/milo.css |
The site-wide toggle in the top bar stores one choice (light / dark / system) that every page and every screen follows; this stage is scoped so the page around it does not change.