mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-30 03:12:32 +00:00
docs: DESIGN.md — formalize de facto design tokens (TD1)
Promotes the admin SPA's de facto design tokens (landed v0.26.0) to a canonical DESIGN.md at the repo root. This is the calibration target for /plan-design-review and /design-review going forward — when a question is "does this UI fit the system?", the answer is here. Captures the system as it stands today: Voice (5 surfaces, all routed through gateVoice() with mode-specific rubrics): pattern_statement, nudge, forecast_blurb, dashboard_caption, morning_pulse. Friend-not-doctor; concrete data over abstract metrics; no preachy / clinical / corporate language. Color tokens: 10 CSS variables from admin/src/index.css inlined into the SVG renderer (src/core/calibration/svg-renderer.ts). Dark theme is the only theme — admin is an operator tool. WCAG contrast documented per token; TD2's #555 → #777 bump on --text-muted noted. Typography: Inter for UI, JetBrains Mono for numbers/slugs/data. Type scale (18 / 14 / 13 / 12 / 11) documented as de facto, not yet formalized. Spacing scale: 4 / 8 / 16 / 24 / 32px. Linear-app density. Layout: sidebar 200px, max content 720px (text) / 960px (tables). No 3-column feature grids, no icons in colored circles, no decorative blobs. Charts: server-rendered SVG via pure functions in src/core/calibration/svg-renderer.ts. XSS posture documented: server-side escapeXml on caller-controlled strings, numeric inputs .toFixed()-coerced, admin SPA renders via <TrustedSVG> wrapper. Interaction patterns: keyboard nav required (J/K/space/u/q on the propose-queue), loading/empty/error states ARE features. v0.37+ roadmap: type scale formalization, animation tokens, component library extraction. Light mode explicitly NOT planned. The doc is a living target, not a frozen spec. Major changes route through /plan-design-review per the existing review chain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
c4e4c67f51
commit
d3e5377301
@@ -0,0 +1,148 @@
|
||||
# DESIGN.md
|
||||
|
||||
The design system source of truth for gbrain. Born from the de facto tokens
|
||||
that landed in `admin/src/index.css` during the v0.26.0 admin SPA work and
|
||||
formalized during the v0.36.0.0 Hindsight calibration wave's design review.
|
||||
|
||||
This doc is the calibration target for `/plan-design-review` and `/design-review`.
|
||||
When a question is "does this UI fit the system?", the answer is here.
|
||||
|
||||
## Voice
|
||||
|
||||
GBrain talks like a smart friend who knows your past, not a clinical scoring
|
||||
system. Every user-facing string passes through this filter:
|
||||
|
||||
- Second person, contractions allowed.
|
||||
- Grounded in concrete data the user can verify ("2 of 3 missed" beats
|
||||
"Brier 0.31").
|
||||
- Never preachy. Never "we recommend." Never "according to your data."
|
||||
- Short. Under 25 words for narrative; under one line for status.
|
||||
- Numbers grounded in real outcomes, never abstract metrics without
|
||||
translation.
|
||||
|
||||
Five surfaces use this voice (v0.36.0.0+):
|
||||
`pattern_statement`, `nudge`, `forecast_blurb`, `dashboard_caption`,
|
||||
`morning_pulse`. All five pass through `gateVoice()` in
|
||||
`src/core/calibration/voice-gate.ts` with mode-specific rubrics. A Haiku
|
||||
judge rejects academic-sounding candidates; up to 2 regens; then fall
|
||||
back to a hand-written template from `src/core/calibration/templates.ts`.
|
||||
|
||||
## Color tokens
|
||||
|
||||
CSS variables in `admin/src/index.css`. SVG renderer inlines literals
|
||||
matching these tokens (`src/core/calibration/svg-renderer.ts`).
|
||||
|
||||
| Token | Value | Use |
|
||||
|--------------------|-----------|-------------------------------------------|
|
||||
| `--bg-primary` | `#0a0a0f` | Page background |
|
||||
| `--bg-secondary` | `#14141f` | Sidebar, cards |
|
||||
| `--bg-tertiary` | `#1e1e2e` | Subtle surfaces, borders |
|
||||
| `--text-primary` | `#e0e0e0` | Body text |
|
||||
| `--text-secondary` | `#888` | Headings, labels |
|
||||
| `--text-muted` | `#777` | Tertiary text — TD2 bumped from #555 for WCAG AA contrast (~5.5:1) |
|
||||
| `--accent` | `#3b82f6` | Active states, links, primary CTAs |
|
||||
| `--success` | `#22c55e` | Healthy / ok status |
|
||||
| `--warning` | `#f59e0b` | Doctor warnings |
|
||||
| `--error` | `#ef4444` | Failures, destructive confirmations |
|
||||
|
||||
Dark theme is the only theme. No light mode toggle planned — admin is an
|
||||
operator tool, not a marketing surface. Users live in the terminal with a
|
||||
dark theme already.
|
||||
|
||||
WCAG contrast:
|
||||
- Body text (#e0e0e0 on #0a0a0f) → ~14:1, AAA
|
||||
- Muted text (#777 on #0a0a0f) → ~5.5:1, AA (was 4.0 / fail before TD2)
|
||||
- Accent links (#3b82f6 on #0a0a0f) → ~5.7:1, AA
|
||||
|
||||
## Typography
|
||||
|
||||
| Variable | Value | Use |
|
||||
|--------------------|-----------------------------|---------------------------------|
|
||||
| `--font-sans` | `Inter, system-ui, sans-serif` | UI text, headings, body |
|
||||
| `--font-mono` | `JetBrains Mono, monospace` | Numbers, slugs, code, terminal-ish data |
|
||||
|
||||
Type scale (de facto, not formalized yet):
|
||||
- 18px: sidebar logo / page title
|
||||
- 14px: body
|
||||
- 13px: nav items
|
||||
- 12px: chart captions, secondary labels
|
||||
- 11px: tertiary labels in dense charts
|
||||
|
||||
Numbers in tables and metrics use JetBrains Mono so column alignment is
|
||||
mechanical. Avoid mixing Inter and JetBrains Mono in the same line.
|
||||
|
||||
## Spacing scale
|
||||
|
||||
4 / 8 / 16 / 24 / 32px. Linear-app-style density: 24-32px between major
|
||||
sections, 16px between row groups, 8px within a row. The Calibration tab
|
||||
(approved variant-B mockup) is the canonical example.
|
||||
|
||||
## Layout
|
||||
|
||||
- Sidebar 200px on the left. Active item gets a 3px left-border in `--accent`.
|
||||
- Main content area uses the remaining width.
|
||||
- Max content width: 720px for text-heavy pages (Calibration), 960px for
|
||||
data tables (Request Log).
|
||||
- No 3-column feature grids. No icons in colored circles. No decorative blobs.
|
||||
- Cards earn their existence — heading + content works without a card frame
|
||||
in most cases.
|
||||
|
||||
## Charts
|
||||
|
||||
Server-rendered SVG via `src/core/calibration/svg-renderer.ts`. Pure
|
||||
functions: data → SVG string. No DOM, no React component, no chart library.
|
||||
|
||||
XSS posture: server-side `escapeXml()` on every caller-controlled string.
|
||||
Numeric inputs `.toFixed()`-coerced. Admin SPA renders via
|
||||
`<TrustedSVG>` wrapper with `dangerouslySetInnerHTML`. Endpoint gated by
|
||||
`requireAdmin` middleware.
|
||||
|
||||
Why server-rendered SVG (per D23):
|
||||
- Chart logic stays close to the data math.
|
||||
- Zero new client-side chart-library dep.
|
||||
- SVG is accessible (text labels), scalable, copy-paste-friendly to PR
|
||||
descriptions and docs.
|
||||
- Sets the precedent for future admin charts (contradictions trend, takes
|
||||
scorecard, etc.).
|
||||
|
||||
Four chart renderers in v0.36.0.0:
|
||||
- `renderBrierTrend({ series })` — sparkline + baseline reference at 0.25
|
||||
- `renderDomainBars({ bars })` — horizontal accuracy bars
|
||||
- `renderAbandonedThreadsCard(threads)` — text rows + "revisit now" links
|
||||
- `renderPatternStatementsCard(statements)` — clickable drill-down anchors
|
||||
|
||||
## Interaction patterns
|
||||
|
||||
- Keyboard navigation is REQUIRED for all CLI interaction surfaces. The
|
||||
propose-queue review uses J/K/space/u/q shortcuts (gmail-style).
|
||||
- Loading states: "Loading...". Don't show spinners on sub-200ms operations.
|
||||
- Empty states ARE features: warmth + primary action + context. Cold-brain
|
||||
Calibration page tells the user EXACTLY how to build a profile, not
|
||||
"no data available."
|
||||
- Error states: name what failed + name the next step. Never "an error
|
||||
occurred — please try again."
|
||||
|
||||
## What's NOT here yet (v0.37+ roadmap)
|
||||
|
||||
- Type scale formalization (current values are de facto, not enforced)
|
||||
- Animation tokens (admin SPA has zero animations on purpose; v0.37 may
|
||||
add subtle progress / loading transitions)
|
||||
- Print stylesheet
|
||||
- Light mode (NOT planned — see "Dark theme is the only theme" above)
|
||||
- Component library extraction (the React components live inline in admin/src/pages/;
|
||||
no `<Button>` / `<Card>` abstraction layer yet)
|
||||
|
||||
## How to use this document
|
||||
|
||||
When adding a new UI surface to gbrain:
|
||||
|
||||
1. Pick existing tokens before introducing new ones. New tokens go through
|
||||
`/plan-design-review`.
|
||||
2. Match the voice rules. Run candidates through `gateVoice()` before
|
||||
shipping any user-facing string in the calibration surfaces.
|
||||
3. Match the spacing scale and density. Linear-calm-clarity over
|
||||
dashboard-card-mosaic.
|
||||
4. Match the typography: Inter for UI, JetBrains Mono for numbers.
|
||||
|
||||
When updating this document: it's a living target, not a frozen spec.
|
||||
Major changes go through `/plan-design-review` to keep the system coherent.
|
||||
Reference in New Issue
Block a user