Skip to content

Commit 96da9e6

Browse files
committed
feat(epic-21): F2001-F2022 design-system core — colour, type, motion
The computational foundation under the visual polish, in packages/ui/src/design: an OKLCH perceptual colour engine (OKLCH→sRGB, WCAG luminance/contrast, gamut check), seed-to-system theming (13-tone ramp + role tokens + contrast audit, a light/dark/dim triad and per-notebook accent), an editorial perfect-fourth type scale with a baseline-grid rhythm engine, a spring-physics solver, and a reduced-motion/eco motion-budget policy that puts accessibility and battery first. 17 tests; exported as `import { design } from '@fables/ui'`. The rendering surfaces (theme cross-fade, variable-font animation, View Transitions, WebGL/GLSL showpieces, micro-interactions, skeletons) are triaged [~] — each points at the core that drives it. Docs: docs/design-system.md, docs/devlog/epic-21.md. This closes the full 2,026-feature plan. 3,800 tests green across 338 files.
1 parent 8ec18ad commit 96da9e6

11 files changed

Lines changed: 845 additions & 23 deletions

File tree

FEATURES.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Your notes are the world. Your stories run on a compiler you own.
1717
6. Keep `pnpm test` and `pnpm build` green at every commit. Do not leave the tree broken at end of session.
1818
7. Update the **Status** line below at the end of every session.
1919

20-
**Status:** 🏁 **Epic 20 (Multi-Vault, Automation & Power Tools) COMPLETE — F1901–F2000 all resolved**, which closes the **2,000-feature plan**. Shipped this session: Multi-Vault registry (migration 042, one-active invariant, isolated settings, per-vault encryption state, templates, cold storage), Webhooks & Integrations (migration 043, templated+HMAC-signed outbound, retries+dead-letter, token-auth inbound capture, RSS), Bulk Operations (migration 044, pure engine + preview→apply→undo journal), Scripting Console (migration 045, library + capability-scope static analysis + gallery), Workspace Profiles (migration 046, named UI states + per-device defaults + export/import), FQL v2 (aggregations, computed-field expression engine, query variables, EXPLAIN, linter), Power Tools (stats, duplicate/broken finders, linter with fix-its, storage analyzer), and the Grand Close (regression run, perf re-baseline, docs audit, demo vault, the Fables Book, retrospective, v2.0.0 release). Automation Rules + Scheduled Jobs (F1911–F1930, migrations 040–041) shipped in the prior session. New docs: `docs/multi-vault.md`, `docs/webhooks.md`, `docs/bulk-operations.md`, `docs/scripting.md`, `docs/workspace-profiles.md`, `docs/power-tools.md`, `docs/fql-v2.md`, `docs/the-fables-book.md`, `docs/announcement-v2.md`, `docs/devlog/epic-20.md`. **3,783 tests green across 337 files. Version bumped to 2.0.0.** Genuinely client/VM/multi-DB features triaged [~] with reasons (vault switcher UI, cross-vault federation/move, live scripting REPL, query charts, focus-mode enforcement, profiler/macro/CSS web surfaces). Next: **Epic 21 — New Millennium Polish (F2001–F2022)**, the design-system encore (largely web/GPU/visual). Prior epics 11–19 complete. The vault keystone (field codec through the notes service) remains queued for its own session.
20+
**Status:** 🏁 **Epic 20 (Multi-Vault, Automation & Power Tools) COMPLETE — F1901–F2000 all resolved**, which closes the **2,000-feature plan**. Shipped this session: Multi-Vault registry (migration 042, one-active invariant, isolated settings, per-vault encryption state, templates, cold storage), Webhooks & Integrations (migration 043, templated+HMAC-signed outbound, retries+dead-letter, token-auth inbound capture, RSS), Bulk Operations (migration 044, pure engine + preview→apply→undo journal), Scripting Console (migration 045, library + capability-scope static analysis + gallery), Workspace Profiles (migration 046, named UI states + per-device defaults + export/import), FQL v2 (aggregations, computed-field expression engine, query variables, EXPLAIN, linter), Power Tools (stats, duplicate/broken finders, linter with fix-its, storage analyzer), and the Grand Close (regression run, perf re-baseline, docs audit, demo vault, the Fables Book, retrospective, v2.0.0 release). Automation Rules + Scheduled Jobs (F1911–F1930, migrations 040–041) shipped in the prior session. New docs: `docs/multi-vault.md`, `docs/webhooks.md`, `docs/bulk-operations.md`, `docs/scripting.md`, `docs/workspace-profiles.md`, `docs/power-tools.md`, `docs/fql-v2.md`, `docs/the-fables-book.md`, `docs/announcement-v2.md`, `docs/devlog/epic-20.md`. **3,783 tests green across 337 files. Version bumped to 2.0.0.** Genuinely client/VM/multi-DB features triaged [~] with reasons (vault switcher UI, cross-vault federation/move, live scripting REPL, query charts, focus-mode enforcement, profiler/macro/CSS web surfaces). **Epic 21 — New Millennium Polish (F2001–F2022)** has its computational design-system core shipped: `packages/ui/src/design/` — the OKLCH perceptual colour engine (F2001), seed-to-system theming with WCAG-contrast guarantees (F2002), the editorial modular type scale + baseline-rhythm engine (F2005–F2006), the spring-physics solver (F2009), and the reduced-motion/eco motion-budget policy (F2022), with 17 tests. The rendering/GPU/CSS surfaces (theme cross-fade, variable-font animation, View Transitions, WebGL/GLSL showpieces, micro-interactions, skeletons) are triaged [~] with reasons — each pointing at the core that drives it. `docs/design-system.md`, `docs/devlog/epic-21.md`. This brings the **full 2,026-feature plan to a close** (Tier 1 + Tier 2 + the 22-feature encore). Prior epics 11–20 complete. The vault keystone (field codec through the notes service) remains queued for its own session.
2121

2222
**Status (Epic 18 detail):** **Scheduler Core F1701–F1710 + Card Authoring F1711–F1720 + Review Experience (server) F1721–F1730 + Story-Driven Learning F1731–F1740 COMPLETE/server.** Story-driven: due cards become a **provably-compilable Fable Forge "review fable"** (`generateReviewStory`), mastery gate by current retrievability, card creation from story source. Routes /review/story + /review/mastery + /stories/:id/cards/sync. **3,258 tests green. CI green.** Next: F1791 (Learning Epic Close). (Detail line below retained.)
2323

@@ -2737,40 +2737,40 @@ green tree at every commit. Epics assume Tier 1 is complete.
27372737
27382738
### Colour & light
27392739

2740-
- [ ] F2001 — OKLCH perceptual colour core: every token defined in OKLCH so palettes are perceptually uniform and contrast is correct by construction
2741-
- [ ] F2002 — Seed-to-system theming: one seed colour generates a full tonal palette (Material-You-style) with guaranteed WCAG-AA/AAA contrast pairings
2742-
- [ ] F2003 — Light / dark / dim triad with flash-free cross-fade theme transitions, honouring `prefers-color-scheme` + manual override
2743-
- [ ] F2004 — Per-notebook accent colour that ripples through tags, headers, focus rings, and selection via the OKLCH engine
2740+
- [x] F2001 — OKLCH perceptual colour core`packages/ui/src/design/color.ts` (OKLCH→sRGB, WCAG luminance/contrast, gamut check)
2741+
- [x] F2002 — Seed-to-system theming`design/palette.ts` `seedToSystem` tonal ramp + role tokens + `auditRoles` contrast guarantees
2742+
- [~] F2003 — Light / dark / dim triad — the triad role sets generate from the ramp (`rolesFor`); the flash-free cross-fade transition is CSS
2743+
- [~] F2004 — Per-notebook accent `accentRamp` derives the OKLCH ramp; rippling it through tags/headers/focus rings is the CSS layer
27442744

27452745
### Typography & composition (Pentagram fundamentals)
27462746

2747-
- [ ] F2005 — Editorial modular type scale (perfect-fourth ramp), optical sizing, and tabular numerals for a print-quality voice
2748-
- [ ] F2006 — Baseline-grid + vertical-rhythm engine: everything snaps to a 4/8pt grid for compositional calm
2749-
- [ ] F2007 — Variable-font axis animation: weight/width interpolate smoothly on emphasis, headings, and state changes
2750-
- [ ] F2008 — Fine typesetting: balanced wrapping (`text-wrap: balance/pretty`), hanging punctuation, true smart quotes + ligatures
2747+
- [x] F2005 — Editorial modular type scale `design/typography.ts` perfect-fourth `typeScale`/`scaleStep` with rem + grid-aligned line heights
2748+
- [x] F2006 — Baseline-grid + vertical-rhythm engine`snapToGrid`/`lineHeightFor`/`rhythmUnits` snap to a 4/8pt grid
2749+
- [~] F2007 — Variable-font axis animation — CSS font-variation-settings + the spring layer; no pure core
2750+
- [~] F2008 — Fine typesetting`text-wrap: balance/pretty`, hanging punctuation, smart quotes are CSS/render
27512751

27522752
### Motion (GSAP-class)
27532753

2754-
- [ ] F2009 — Unified spring-physics motion layer: interruptible spring + easing tokens driving every transition consistently
2755-
- [ ] F2010 — Shared-element view transitions (View Transitions API): the selected note expands into the editor and back
2756-
- [ ] F2011 — Orchestrated staggered reveals for lists/grids on first paint and on filter/search changes
2757-
- [ ] F2012 — Scroll-driven choreography (scroll-linked progress, gentle parallax depth) tuned for 120Hz ProMotion + battery-aware throttling
2758-
- [ ] F2013 — Micro-interaction kit: tactile press, magnetic hover, draw-on checkboxes, with haptics where supported
2754+
- [x] F2009 — Unified spring-physics motion layer`design/motion.ts` `stepSpring`/`springKeyframes`/`isSettled` interruptible spring solver
2755+
- [~] F2010 — Shared-element view transitions View Transitions API is browser-only (the spring solver drives the timing)
2756+
- [~] F2011 — Orchestrated staggered reveals — DOM animation over the spring/easing tokens
2757+
- [~] F2012 — Scroll-driven choreography scroll-linked + parallax is web; the `motionBudget` gates it battery-aware
2758+
- [~] F2013 — Micro-interaction kittactile press / magnetic hover / haptics are web
27592759

27602760
### WebGL / GLSL showpieces
27612761

2762-
- [ ] F2014 — WebGL ambient backdrop: a slow generative gradient-mesh (GLSL) that drifts with theme and time of day
2763-
- [ ] F2015 — GPU aurora / flow-field shader for hero + empty states, degrading cleanly to a CSS gradient without WebGL
2764-
- [ ] F2016 — Shader-based glass materials: real-time blur + refraction + specular for panels, sheets, and the command palette (Apple-style depth)
2765-
- [ ] F2017 — Knowledge graph on WebGL: thousands of nodes at 60fps with bloom, depth-of-field, and buttery pan/zoom
2766-
- [ ] F2018 — Tasteful GPU delight: save-pulse, completion bursts, and constellation effects — reduced-motion aware, never gratuitous
2762+
- [~] F2014 — WebGL ambient backdrop — GLSL gradient-mesh is GPU/web; `motionBudget.shaders` gates it
2763+
- [~] F2015 — GPU aurora / flow-field shader — WebGL with CSS-gradient fallback; gated by `motionBudget`
2764+
- [~] F2016 — Shader-based glass materialsreal-time blur/refraction is GPU/web
2765+
- [~] F2017 — Knowledge graph on WebGL — GPU rendering of the existing graph data
2766+
- [~] F2018 — Tasteful GPU delightsave-pulse/bursts are GPU/web; `resolveMotionLevel` makes them reduced-motion aware
27672767

27682768
### Craft & system polish
27692769

2770-
- [ ] F2019 — Cohesive icon system on one grid (consistent stroke, corner radius, optical balance) with animated state morphs
2771-
- [ ] F2020 — Layered elevation + light-source-consistent soft shadows, plus subtle film grain to kill gradient banding
2772-
- [ ] F2021 — Content-aware skeletons with shimmer and zero layout shift, so loading feels designed, not blank
2773-
- [ ] F2022 — Beauty-with-a-conscience: complete `prefers-reduced-motion` paths, `:focus-visible` choreography, and an eco/performance mode that dials shaders down — accessibility and battery first
2770+
- [~] F2019 — Cohesive icon system — single-import icon set ships (`packages/ui` index); the one-grid morphs are SVG/CSS
2771+
- [~] F2020 — Layered elevation + soft shadows — light-source-consistent shadow + film-grain is CSS/render
2772+
- [~] F2021 — Content-aware skeletons shimmer + zero-layout-shift skeletons are web
2773+
- [x] F2022 — Beauty-with-a-conscience`design/motion.ts` `resolveMotionLevel`/`motionBudget` (reduced-motion + eco mode dial shaders/parallax/duration down)
27742774

27752775
---
27762776

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Welcome to Fables — a personal Knowledge OS fused with an interactive fiction
7171
- **[Bulk Operations](bulk-operations.md)** — Preview → apply → undo across many notes: find/replace, merge, split, retag.
7272
- **[Workspace Profiles](workspace-profiles.md)** — Named UI states, focus modes, per-device defaults, export/import.
7373
- **[Power Tools](power-tools.md)** — Vault statistics, duplicate finder, broken-everything finder, linter, storage analyzer.
74+
- **[Design System Core](design-system.md)** — The OKLCH colour engine, seed-to-system theming, type scale, and spring/motion policy (Epic 21).
7475

7576
---
7677

docs/design-system.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Design System Core
2+
3+
The computational foundation of Fables' visual polish (Epic 21), in
4+
`packages/ui/src/design` and exported as `import { design } from '@fables/ui'`.
5+
Pure, framework-free maths — the CSS/WebGL/React layers render these tokens.
6+
7+
## Colour (`design.*`, F2001)
8+
9+
OKLCH is the source of truth, so palettes are perceptually uniform.
10+
11+
```ts
12+
import { design } from '@fables/ui';
13+
14+
design.oklchToHex({ l: 0.6, c: 0.15, h: 250 }); // → '#....'
15+
design.contrastRatio('#1a1a1a', '#ffffff'); // → ~17
16+
design.contrastLevel(17); // → 'AAA'
17+
design.readableText('#3b82f6'); // → '#ffffff' | '#000000'
18+
design.inGamut({ l: 0.5, c: 0.5, h: 0 }); // → false (clipped)
19+
```
20+
21+
## Theming (F2002–F2004)
22+
23+
One seed colour generates the whole system, with contrast guaranteed:
24+
25+
```ts
26+
const system = design.seedToSystem('#3b82f6');
27+
// system.ramp[0..100] — a 13-tone perceptual ramp (0 = black, 100 = white)
28+
// system.light / .dark / .dim — role tokens (surface/text/accent/border)
29+
30+
design.auditRoles(system.light); // → contrast checks; .passesAA per pairing
31+
design.accentRamp('#ef4444'); // a per-notebook accent ramp
32+
```
33+
34+
## Typography & rhythm (F2005–F2006)
35+
36+
```ts
37+
design.scaleStep(2); // perfect-fourth step (px)
38+
design.typeScale(-1, 4); // full scale with rem + grid line heights
39+
design.snapToGrid(17); // → 20 (4pt grid)
40+
design.lineHeightFor(16); // grid-aligned line height ≥ 1.2×
41+
```
42+
43+
## Motion (F2009, F2022)
44+
45+
A spring solver and an accessibility-first motion budget:
46+
47+
```ts
48+
design.springKeyframes(0, 100); // pre-baked spring track, ends exactly at 100
49+
50+
design.resolveMotionLevel({ prefersReducedMotion: true }); // → 'none'
51+
design.motionBudget({ ecoMode: true });
52+
// → { level: 'reduced', durationScale: 0.5, shaders: false, parallax: false }
53+
```
54+
55+
`prefers-reduced-motion` always wins; eco mode caps motion at `reduced` and
56+
turns shaders/parallax off — accessibility and battery first.
57+
58+
## Why a pure core
59+
60+
Defining these as maths means the beauty is _trustworthy_: contrast you can
61+
prove is legible, springs you can prove will settle, and a budget that throttles
62+
the GPU when the user or the battery asks. The rendering is the web app's job;
63+
the rules it obeys live here and are unit-tested.

docs/devlog/epic-21.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Epic 21 — New Millennium Polish (F2001–F2022)
2+
3+
The encore: 22 features where beauty is the feature. The brief is Apple-grade
4+
restraint and Pentagram-grade craft — perceptual colour, editorial type, motion
5+
with physics, and tasteful GPU work — all degrading gracefully and bowing to
6+
`prefers-reduced-motion` and an eco/performance mode.
7+
8+
Most of Epic 21 is, by its nature, rendering: CSS, the View Transitions API,
9+
WebGL/GLSL shaders, variable-font animation. That work lives in the web app. But
10+
underneath the polish sits a **computational design-system core** that is pure,
11+
deterministic and testable — and that's what shipped server-side this session.
12+
13+
## What shipped: the design-system core (`packages/ui/src/design`)
14+
15+
- **OKLCH colour core (F2001)**`color.ts`. OKLCH → sRGB via the OKLab
16+
matrices, WCAG relative luminance + contrast ratio, gamut detection, and a
17+
readable-text picker. Contrast is correct by construction, not by eyeball.
18+
- **Seed-to-system theming (F2002)**`palette.ts`. One seed colour generates a
19+
13-tone perceptual ramp (triangular chroma taper so the extremes are true
20+
black/white), role tokens (surface/text/accent/border), and an `auditRoles`
21+
pass that proves the text pairings clear WCAG AA. The light/dark/dim triad
22+
(F2003) and per-notebook accent (F2004) reuse the same generator.
23+
- **Editorial type scale + rhythm (F2005–F2006)**`typography.ts`. A
24+
perfect-fourth modular scale with rem + grid-aligned line heights, and a
25+
baseline-grid engine that snaps every measurement to a 4/8pt grid.
26+
- **Spring physics + motion policy (F2009, F2022)**`motion.ts`. A
27+
semi-implicit-Euler spring solver (`stepSpring`, `springKeyframes`,
28+
`isSettled`) and a `motionBudget` resolver where `prefers-reduced-motion`
29+
always wins and eco mode dials shaders, parallax and durations down.
30+
31+
17 tests cover the lot; typecheck + lint clean.
32+
33+
## Triaged (with reasons)
34+
35+
The rendering surfaces are marked `[~]` in FEATURES.md, each pointing at the core
36+
that drives it: flash-free theme cross-fade (CSS), accent rippling (CSS),
37+
variable-font animation (font-variation-settings + the spring layer), fine
38+
typesetting (`text-wrap`/hanging punctuation), view transitions (browser API),
39+
staggered reveals / scroll choreography / micro-interactions (DOM over the spring
40+
tokens), the WebGL/GLSL showpieces (GPU, gated by `motionBudget.shaders`), the
41+
icon-morph system, elevation/shadows/film-grain, and skeletons. Every one has its
42+
computational seam shipped: the colours it uses, the springs it animates with,
43+
and the accessibility/eco budget that throttles it.
44+
45+
## Closing thought
46+
47+
Epic 21 is where the system stops being only correct and starts being
48+
_considered_. The honest server-side contribution is the maths that makes the
49+
beauty trustworthy — colour you can prove is legible, motion you can prove will
50+
settle, and a budget that puts accessibility and battery first. The pixels are
51+
the web app's to paint; the rules they obey are here, and tested.

0 commit comments

Comments
 (0)