Enso · sitemap

Why

What each token is, on Design System, says nothing about why. This page does. Every token, and every spec in docs/specs/, sits at the bottom of the chain of reasons above it, from reckon why, root at the top, with its own ## Why, read from the file so there is one copy of the reasoning.

  1. node figures-from-poser — Every exercise figure in the app comes from the poser SDK in ../poser — rungs, gates, the leg-length measurement. No commissioned or stock art; a pose poser cannot draw yet is a labelled placeholder, not a drawing. (horizon short; until alpha; open)
    parent of ladder-metadata-local · docs/strategy.md:343
  2. node ladder-metadata-local — Any fact about an exercise that poser doesn't carry yet is hardcoded in this app's data first: the FIT ladder's in src/lib/ladder (hold or movement, which keyframes to show, what a rung needs, the feel/verify checks), a routine block's in its .routine.json (hold or reps, each way, alternating, side wording). Where poser has the fact, poser wins. A field moves into poser once the hardcoded version has proven good enough and clear enough to scale: used across several exercises without special cases. The app's copy is then deleted and the resolver reads poser. (horizon short; until poser's corpus carries exercise metadata; open)
    governs @routines; child of figures-from-poser · docs/strategy.md:439
  3. node measurement-first — Above-average adults lack measurable goals, not workouts. A repeatable assessment that places someone on ladders, and a loop that moves them up, is worth more than any library of workouts. (horizon long; until beta; open)
    parent of the-loop · docs/strategy.md:43
  4. node local-first — Everything a user records stays in their browser. No backend, no accounts, no sync, no analytics that transmit results. (horizon short; until beta; open)
    governs @local-store; child of measurement-first · docs/strategy.md:316
  5. node the-loop — A scorecard on its own brings nobody back. What alpha has to test is the whole loop, small: assess, place on ladders, generate today's blocks, execute calmly, feed back so a rung moves. Build it end to end at the smallest size that closes, before any one part of it is deep. (horizon short; open)
    governs @screens; child of measurement-first · docs/strategy.md:81
  6. node earn-its-keep — Everybody already knows they should stretch more. The app was never about telling people what to do; it is about getting them to do it and to achieve something, and it keeps them however it can. Feedback that moves a rung, a routine finished, a goal reached: each is marked, and the app earns its place on the phone by those, not by being clever. (horizon short; open)
    governs @screens; child of the-loop · docs/strategy.md:118
  7. node quiet-instrument — While a block runs, the app is an instrument, not a show. The user's attention is on their body, and the screen sits in their peripheral vision, which exists to notice motion; so the screen holds still, shows one thing at the size the distance needs, and moves only as a signal: something changed, or something can be touched. It brings no atmosphere of its own, no music, no mood. It has to be at home on a hotel gym bench with the TV on, on a hotel room floor at night, and on a living room floor with family around, and it does that by borrowing the room's atmosphere rather than adding one. (horizon short; open)
    governs @screens; child of earn-its-keep · docs/strategy.md:158
  8. node brand — There is no brand yet, so there is no objective opinion on a themed palette. Until there is one, the palette is neutral, paper and ink with one accent, and the palette standard names this node as the thing that changes it. (horizon short; until a brand exists; open)
    governs @sitemap; child of quiet-instrument · docs/strategy.md:286
  9. node calm-execution — On the run screen, quiet-instrument cashes out as three rules. The type scale is named for where it is read from, near, floor and room, and the one number that is counting is always at room scale. At most one thing changes at a time, and it moves because it means something; a steady count, like the rest's wipe, may keep running under it. The change the user is waiting for is cued three ways at once, seen, felt and heard. Every token in the design system is a consequence of one of these, and a token that can't say which doesn't belong. (horizon short; open)
    governs @screens; child of quiet-instrument · docs/strategy.md:207
  10. node no-voice — The app does not talk. No coaching voice, no spoken routine, and the "Switch sides" the run wireframe has the app say becomes a tone. A voice is the app performing for the room, which is the one thing quiet-instrument rules out in a living room. (horizon short; until a coaching feature exists, or voice-guided routines are something the user chooses; open)
    governs @screens; child of quiet-instrument · docs/strategy.md:250
  11. adr adr-006 — The printed sheet is gone
    names @screens · docs/decisions/adr-006-no-printed-sheet.md
  12. adr adr-004 — Sheet figures are baked before a deploy, on request
    names @figures · docs/decisions/adr-004-baked-sheet-figures.md
  13. adr adr-005 — Clips are baked before a deploy, and the run screen plays them
    names @screens · docs/decisions/adr-005-baked-clips.md
  14. adr adr-002 — One hand-authored routine ships in alpha
    names @routines · docs/decisions/adr-002-routine-v0-in-alpha.md
  15. adr adr-003 — No safety gate in alpha
    names @screens · docs/decisions/adr-003-no-safety-gate-in-alpha.md
  16. adr adr-001 — A Next.js web app, with figures from poser
    names @screens · docs/decisions/adr-001-web-stack-and-poser.md
  17. component batteries — The catalogue: tests, kinds, sides, ladders and rung wording, gates, expert benchmarks, and which poser exercise and level draws each rung. Progressions (`specs/progressions.md`) live here: each is an entry naming its levels, their capture kinds, figures, sentences, prerequisites and routines, and the default level. Data, plus the straddle-angle formula and the 1.4 × L target. Adding a test or a progression means adding an entry here and nothing in the screens. Today it holds the pre-rebuild four-summit battery and no progressions; the baseline on the POC 3 board moved to beta.
    owns src/lib/batteries/** · docs/architecture.md:42
  18. component figures — Every illustration the app shows, from poser (`figures-from-poser`). The only place `@poser/sdk` is imported; @batteries names a figure by poser exercise and level, and this turns that into a picture. A test poser cannot draw yet names its gap instead, and this draws a labelled placeholder (`specs/poser-gaps.md`). The SDK is WebGL, so drawing happens in a browser: the visitor's, or the bake's. One shared viewer renders each figure once to an image, so a page of rungs costs one WebGL context. The worksheet's figures come from a second, fixed-camera mode — one scale and floor line per sheet, as poser's own pose sheets draw them. Those sheet figures can be baked before a deploy into `public/figures/` (adr-004); production serves a baked one when its version matches, and draws live otherwise. The bake covers every figure the routines draw and, since 2026-10-17, poser's whole library, for the Poses page (`/poses`, lib-1a in @screens), which lists what poser draws and what each pose says about itself.
    owns src/figures/**, src/app/(app)/bake-figures/**, scripts/bake-figures.mjs, scripts/bake-clips.mjs, public/poser/clips/** · docs/architecture.md:145
  19. component local-store — The spec §7 data model in IndexedDB: user, sessions, results. No sensor reps. Also the CSV and JSON export of all of it, and schema versioning. The only module that persists anything. Since the rebuild only @figures writes to it, as a cache; no screen saves a session, and alpha's "nothing is saved during a run" means the first write is the end-of-session feedback, not built.
    owns src/store/** · docs/architecture.md:164
  20. component routines — Routines as data (`specs/routine-v0.md`, `adr-002`): `.routine.json` files, a registry, and the resolver that joins each move to its poser level — caption, per side — and writes every dose and header string. Hand-authored, shipped with the app, never stored per user. Hold or reps is interim metadata here until poser carries it (`ladder-metadata-local`).
    owns src/lib/routines/** · docs/architecture.md:78
  21. component screens — Being rebuilt from the wireframe boards (`milestones/alpha.md`). Each screen is planned in @sitemap first: `src/screens/<id>/wireframe.md` describes it, and an agent builds from that file, one screen at a time, replacing the sketch whole. Every page shares the `palette` token from the app's root layout (`standards/palette.md`). Owns no maths: every number it shows comes from @scoring, @batteries or @routines.
    owns src/app/**, src/components/**, src/screens/** · docs/architecture.md:93
  22. spec The run screen's terms

    • calm-execution: at most one thing changes at a time, and it moves because it means something. Rules 2 and 4 are this rule, made concrete for the run screen.
    • quiet-instrument: while a block runs, the screen is an instrument, not a show. A figure that disagrees with the band is the screen contradicting itself.
    • One word per meaning, because these words reach agents through prompts and this file. A word with two meanings ("active") is a bug report nobody can act on.

    Specifies @screens · docs/specs/run-screen.md

  23. spec Progressions

    • measurement-first: people lack measurable goals, not workouts. A progression is the measurement made into a path: where you are, and what the next level needs.
    • assessment-over-precision: every attempt is entered by hand, from a count, a timer or taps on what happened. The outcome is suggested, and the user confirms it.
    • self-comparison-only: a level is a standard to meet, not a percentile. Nothing on the page compares one user with another.
    • figures-from-poser: every level is drawn, so a stranger can try it without reading.
    • Plain words, because they reach users as well as agents. The owner chose "progression", "level" and "assessment" over coined terms on 2026-10-14. Why alpha narrowed to one progression is the owner's to write; the milestone leaves it blank.

    Specifies @batteries, @screens, @routines, @figures, @local-store · docs/specs/progressions.md

  24. component sitemap — The design tracker at `/sitemap`. It has three parts. **Screens** splits the page in two. On the left is one entry per wireframe board option, read from `src/screens/<id>/wireframe.md`. On the right is the whole board, from `src/sitemap/board/`. Selecting an entry (`/sitemap/#poc-1a`) expands its written wireframe in place and pans the board to that option. Clicking an option on the board selects its entry. Each entry also shows whether options still compete for its slot, and whether its screen is live. **Design System** is tokens, primitives and blocks as stories, each with live prop controls, and each story names the screens that use it. **Why** (`/sitemap/why`) reads each token's standard and each spec (a doc in `docs/specs/` whose frontmatter names `components:`, as reckon counts one), shows its `## Why` section, and draws one chain of reasons above them all, merged from each one's `reckon why --json` so every step is printed once, root first; a token or a spec links to its reasoning without a copy of it. A spec appears there as soon as it's written, and a test fails until it has a `## Why`. A dev tool shipped in the static export; it reads the filesystem, and reckon when installed, only at build time.
    owns src/sitemap/**, src/design-system/**, src/app/(app)/sitemap/** · docs/architecture.md:104
  25. standard Palette · token

    Lavender and clay: four roles (ground, ink, ink-2, signal) in light and dusk, each with its contrast against ground, and the type scale read from 1.5, 3 and 10 feet.

    • It serves calm-execution, whose not: rules out faint colour. A run screen is read from the floor, so the second ink is 6.5:1. Hierarchy comes from size (near, floor, room), not from fading things out.
    • It serves quiet-instrument: the screen borrows the room's atmosphere and adds none of its own. The ground is nearly white, with only a tint of lavender, so it sits as easily in a hotel gym as on a living room floor. A cream ground would be a mood.
    • Cool ground, warm accent. The ground's hue (295) sits almost opposite clay's (38), so the signal stands out more against lavender than against a warm plaster at the same contrast ratio. That matters for a colour seen out of the corner of the eye. The ground is after Bevel's page (#F8F7FC), chosen by the owner on 2026-10-09 over plaster, olive, indigo and the ensō's seal red.
    • One accent, because calm-execution allows one moving thing at a time. When the signal colour shows up, something is asking for attention. A second hue, like the draft's sage for "resting", would give the eye two things to check. Rest is a state, so the inactive row's countdown shows it and no colour does. On the run screen the signal marks the last 5s, the dots of a countdown, because that's the change being waited for (poc-1f.b → The player).
    • Dusk is for the hotel room at night. It runs darker than a typical dark theme (ground L 0.17) and dims ink to 12.5:1, so the phone on the floor doesn't light up the room.
    • It's provisional under brand. Until there is a brand, this stays paper and ink with one accent. Lavender and clay is that, with the paper cooled.

    Applies to @screens, @sitemap · docs/standards/palette.md · active

  26. standard Duration · token

    A length of time on a run screen, written as 45s, 1m 43s or 2m: no colon, no leading zero, no space before the unit. Whole minutes drop the seconds.

    • It serves calm-execution: a run screen is read from five feet with the device on the floor, so one hold has to read as one number, in one shape, everywhere it appears.
    • A run screen puts a dose, a step and a countdown side by side: "hold for 45s", a band reading "hold 45s", a rest counting "9s". Each written its own way ("45 s", "0:45", "0:09") reads as three different numbers for one hold.

    Applies to @screens, @routines, @sitemap · docs/standards/durations.md · active