Skip to content

Latest commit

 

History

History
148 lines (116 loc) · 6.56 KB

File metadata and controls

148 lines (116 loc) · 6.56 KB

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.1.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.1.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.1.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.