Files
whisper_web/DESIGN.md
T
Lucas WintherandClaude Opus 5.5 c0528af082 Wrap transcript card actions under the title on narrow screens
Polish pass on the translate panel: the four export buttons overflowed
both transcript cards at 390 px. Also record the headless-Chrome
translation run and a re-measured bench in D-WS4b.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 00:19:04 +01:00

2.7 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, …), with modifier classes like -selected, -active, -disabled. Interactive states use :hover:enabled and :focus-visible. .visually-hidden exists for screen-reader-only text. Card headers (.transcript-header: title + export/Copy buttons) wrap, so on a phone the buttons move under the title instead of overflowing the card.

Secondary disclosures (.storage-manager, .translate-panel) share one look: a 12px-radius --panel card with a semibold <summary>, muted 0.85rem hints, outlined 8px buttons. Inside the translate panel the one action (.translate-button) is the only accent-outlined button and fills with --accent / --on-accent on hover; a translation renders as a second .transcript card below it rather than a card nested inside the panel.