Files
whisper_web/DESIGN.md
T

2.2 KiB
Raw Blame History

Design

Derived from the shipped src/index.css (single stylesheet, plain CSS, no framework). Describes what exists, not an aspiration. Update in the same commit as visual changes.

Foundations

  • Theme: dark by default, light when the OS prefers it (@media (prefers-color-scheme: light) overrides the tokens; no in-app toggle). <meta name="theme-color"> has a variant per scheme. The PWA manifest and icons stay dark (#16181d).
  • Tokens (:root, dark → light): --bg #16181d → #f5f6f8 · --fg #e8e8e8 → #1a1d23 · --muted #9aa3b2 → #5b6372 · --panel #1f232b → #ffffff · --border #343a46 → #d3d8e0 · --surface-raised (inputs, code) · --surface-selected (selected/drag-active) · --accent #7aa2f7 → #2f5bd3 + --on-accent · --success / -bg / -border · --danger / -muted / -bg / -border + --on-danger · --live (recording) · --shadow. No raw colours outside the token block — add a token (with both values) instead.
  • Contrast: every text/background token pair is ≥ 4.5:1 in both themes (checked when the light theme landed, D-037). Re-check any new pair.
  • Type: Inter Variable, self-hosted (@fontsource-variable/inter, 7 unicode-range subsets served from /fonts/, precached; see scripts/fonts.ts, D-037). Body line-height 1.5; h1 2.2rem / 1.15.
  • Layout: single centred column, .app { max-width: 720px; padding: 2.5rem 1.25rem 3rem; gap: 1.5rem }, body { min-width: 320px }.
  • Radius: 8px for controls (most common); 10–14px for panels/cards; 999px for pills/badges.
  • Motion: 0.15s colour/border transitions; pulse (live dot) and blink (cursor) animations, disabled under prefers-reduced-motion.
  • Browser surfaces: accent-color and ::selection come from --accent.

Components

One BEM-ish class block per React component in src/components/ (.model-picker, .dropzone, .live-controls, .engine-toggle, .auth-panel, .update-toast, .vocabulary-hint, …), with modifier classes like -selected, -active, -disabled. Interactive states use :hover:enabled and :focus-visible. .visually-hidden exists for screen-reader-only text.