Files
Lumotia/docs/release/v0.3-tactile-quietware.md
Jake db9c50c548 v0.3 Phase 3: status grammar — LumotiaNotice left-bar refactor
Phase 3 audit found that both LumotiaStatusPill and LumotiaNotice
already shipped in v0.2 Phase 5. Phase 3 reduced to an audit-and-adapt
pass.

LumotiaStatusPill ($lib/components/StatusPill.svelte) is already
correct for quietware. Pattern: neutral pill background + neutral
label text + role colour confined to a 6x6 px dot. Colour is
supplementary, label is always perceivable. Works unchanged across
all three quietware modes. No changes shipped.

LumotiaNotice ($lib/ui/LumotiaNotice.svelte) refactored to the
left-bar accent pattern. Previously the role colour rendered on the
icon outline and on the entire surround border at 30% opacity; in
quietware light mode that left the bright #FFCD00 caution colour
faded against cream paper. New pattern:

  - 4-px solid LEFT border in the tone colour, 100% opacity.
  - Soft tone-tinted background (10% opacity) for ambient cue.
  - Subtle neutral outer border on the other three sides.
  - Icon, title and body text all use --color-text.

Visible signal lives on the large bar (works at any contrast level);
foreground text uses the always-legible neutral. Matches Material
Design "banner with leading accent" and IBM Carbon "inline
notification" guidance. ARIA semantics (role="alert" for danger,
role="status" for the rest) preserved.

Design-system-v2 preview route already imports both primitives. The
updated Notice renders correctly with the existing preview content;
no additional wiring required.

Caution remains a fill-only convention on cream by design. Any
darkened yellow reads as olive ("looks like poop", per Jake), so the
fill-only rule stays in force and this pattern delivers it cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 13:03:00 +01:00

242 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lumotia v0.3 — Tactile Quietware
> Calm enough for overloaded brains, structured enough to recover thoughts, tactile enough to feel like a local desktop tool rather than SaaS.
The v0.3 release reframes Lumotia around one thesis: a low-cognitive-load capture instrument. Built on the WCAG 2.2 + W3C COGA + NN/G evidence base, validated against the four HMRC accessibility personas that map most directly onto a dictation-first desktop tool.
This document is the single source of truth for v0.3. Phase log, regression diary, palette spec and font stack all live here.
---
## Source brief
Locked 2026-05-15 from Jake's design brief and three rounds of capture-pipeline iteration.
- Palette: `inputs/inbox/2026-05-15-lumotia-colour-layout-changes.md` plus the colour-palette refinements at `inputs/inbox/2026-05-15-re-lumotia-v03-renders-revised-palette-typography-.md`.
- Personas: HMRC Virtual Empathy Hub, eight personas at `https://personas-prototype.herokuapp.com/`.
- Accessibility tools: DfE manual at `https://accessibility.education.gov.uk/tools-testing/tools`.
## Rule set
The five rules every v0.3 PR has to clear.
| Rule | Meaning |
|---|---|
| Texture = atmosphere | Static global grain. No per-panel noise. No motion. Default 6%, slider 5 to 8% in advanced. |
| Colour = status | Brand palette IS the semantic palette. Brand chroma earns its keep by signalling state. Decorative colour is forbidden. |
| Layout = calm | Every page uses the same skeleton. Files, Tasks, History and Dictation must not invent their own structure. |
| Motion = feedback only | Animation only for recording, loading, success and failure. Honour `prefers-reduced-motion` at root. |
| Settings = progressive disclosure | One sectional tab visible at a time. Eight tabs. No long scroll. |
---
## Palette
Locked 2026-05-15 from Jake's color.adobe.com primaries. Each primary is used literally where it clears WCAG AA on the relevant background. Where it does not, a text-safe sibling at the same hue and saturation is derived.
### Source primaries
| Role | Primary | Hue | Notes |
|---|---|---|---|
| `--danger` | `#FF0700` | 2deg | Pure red |
| `--info` | `#000AFF` | 238deg | Pure blue |
| `--success` | `#00FF56` | 140deg | Pure green |
| `--caution` | `#FFCD00` | 48deg | Pure yellow |
### Light mode
Cream paper base. Jake's blue passes AAA on cream and is used literally. The other three are darkened siblings for AA text contrast, with caution kept fill-only because any darkened yellow reads as olive or mustard ("looks like poop").
| Token | Hex | Contrast on `#FBF8F2` | Notes |
|---|---|---|---|
| `--color-bg` | `#FBF8F2` | Base | Cream paper |
| `--color-text` | `#1D1B18` | 14.43 AAA | Near-black |
| `--color-info` | `#000AFF` | 7.96 AAA | Jake literal |
| `--color-danger` | `#E60600` | 4.51 AA | Sibling derived from `#FF0700` |
| `--color-success` | `#00852D` | 4.51 AA | Sibling derived from `#00FF56` |
| `--color-caution` | `#FFCD00` | 1.42 (fill-only) | Jake literal, fill-only convention |
**Caution is fill-only on cream.** Pill backgrounds, dots, left-border accents and icons take `--color-caution`. Foreground text inside a caution-coloured pill stays `--color-text`. Matches Material, GOV.UK and IBM Carbon practice.
### Dark mode
Lifted Coffee Bean base. Jake's green and yellow primaries already clear AAA on the dark surface and are used literally. Red and blue need lifting because pure-saturated dark hues fail against a dark background.
| Token | Hex | Contrast on `#2A1620` | Notes |
|---|---|---|---|
| `--color-bg` | `#2A1620` | Base | Lifted Coffee Bean |
| `--color-text` | `#F3EFE7` | 13.85 AAA | |
| `--color-info` | `#7076FF` | 4.64 AA | Lifted from `#000AFF` |
| `--color-danger` | `#FF2A24` | 4.54 AA | Lifted from `#FF0700` |
| `--color-success` | `#00FF56` | 12.51 AAA | Jake literal |
| `--color-caution` | `#FFCD00` | 11.33 AAA | Jake literal |
### High contrast mode
Same four hues retained so role recognition does not flip between modes. Saturation 80%, lightness 70%. Zero texture, no translucent overlays.
| Token | Hex | Contrast on black |
|---|---|---|
| `--color-bg` | `#000000` | Base |
| `--color-text` | `#FFFFFF` | 21.00 AAA |
| `--color-info` | `#757AF0` | 5.80 AA |
| `--color-danger` | `#F07975` | 7.70 AAA |
| `--color-success` | `#75F09F` | 14.72 AAA |
| `--color-caution` | `#F0D875` | 14.78 AAA |
---
## Typography stack (V4 pairing, locked 2026-05-15)
Three production fonts. Self-hosted as WOFF2. No CDN dependency.
| Role | Font | Licence | Used for |
|---|---|---|---|
| Body and UI | Work Sans (variable) | OFL | Headers, labels, controls, sidebar, body, transcript surface |
| Brand moments | Young Serif | OFL | Wordmark, splash, empty-state hook copy, About modal |
| Mono | JetBrains Mono | Apache 2.0 | Logs, model IDs, file paths, hotkey strings |
Atkinson Hyperlegible Next and OpenDyslexic stay as opt-in accessibility fonts via Settings. Archivo, Lexend and Instrument Serif from v0.2 stay shipped during v0.3 transition; future release may remove them after persona testing.
---
## Persona test gates
Each phase must pass these four manual gates before merge. Tools and tasks from the DfE manual.
| Persona | Condition simulated | Primary risk for Lumotia | Gate |
|---|---|---|---|
| Pawel | Autistic | Sensory load, predictability, motion sensitivity | Empty states speak. No surprise motion. Same skeleton on every page. |
| Simone | Dyslexic | Transcript readability, dense paragraphs | Transcript body uses Work Sans at 16px minimum, line-height ≥ 1.6, comfortable measure. |
| Chris | Rheumatoid arthritis | Click target size, keyboard fallback for every action | All interactive targets ≥ 44 x 44 px. Every action reachable by keyboard with visible focus ring. |
| Ron | Older user, multiple conditions | Combined: vision + cognitive + motor | All three of the above hold simultaneously. |
Medium-priority personas (Claudia magnifier, Saleem deaf) get explicit checks at Phase 5. Lower-priority personas (Ashleigh screen reader, Helena dyscalculia) get checks at v0.4.
---
## Phase 0 — Accessibility tools checklist
Manual gov.uk DfE tools applied to every v0.3 phase before merge. Tools that map onto a Tauri webview tested via the same browser-preview surface already shipped in v0.2.
- [ ] Contrast Checker. All palette pairs verified against WCAG AA. Annotated in the relevant phase commit message.
- [ ] axe DevTools. Run on every page after the phase migrates it.
- [ ] Resize Text. 200% zoom does not break any layout.
- [ ] Text Spacing. Increased letter, word, line spacing per WCAG 1.4.12 does not clip content.
- [ ] Target Size. All interactive targets ≥ 44 x 44 px (WCAG 2.5.8).
- [ ] HeadingsMap. Settings sectional refactor preserves a sensible h1 → h6 hierarchy.
- [ ] Blur. Smoke check that primary actions remain legible under simulated low vision.
- [ ] Screen reader smoke test. NVDA or Orca on the Settings page after Phase 3.
A future-Phase CI step will automate axe-core + contrast checks. Out of scope for v0.3 per Jake's 2026-05-15 decision.
---
## Phase plan
Each phase ships as its own PR. Each is flag-gated by `html[data-design="quietware"]`. The current v0.2 user-facing surface is unaffected until Phase 6 promotes quietware to the default.
### Phase 1 — Tokens. (this PR)
- New file `src/design-system/v0.3-quietware-tokens.css` with three palette scopes (dark, light, high-contrast).
- Self-hosted Work Sans (variable), Work Sans Italic (variable), Young Serif (static) at `src/fonts/`.
- Import wired in `src/app.css` directly after the tailwind import. Inert until `data-design="quietware"` is present on `<html>`.
- No component changes. No behavioural changes.
### Phase 2 — Build flag wiring.
- `VITE_LUMOTIA_QUIETWARE=1` build-time env var sets `data-design="quietware"` on `<html>` via `src/routes/+layout.svelte`.
- Manual override path stays: dev tools, or a Settings toggle gated behind the same flag.
### Phase 3 — Status grammar primitives.
- `LumotiaStatusPill`, `LumotiaNotice` with icon + label + body + actions.
- Caution is fill-only across both. Foreground text uses `--color-text`.
- Component preview added to `src/routes/design-system-v2/`.
### Phase 4 — Settings sectional refactor.
- Split the 2 791 LOC `SettingsPage.svelte` across eight tabs: Start Here, Models, Output, Vocabulary, Tasks, Accessibility, Privacy, Advanced.
- Texture-opacity slider lives in Accessibility. Range 0.05 to 0.08. Default 0.06.
- High-contrast toggle in Accessibility. Toggle overrides system `prefers-contrast` query when set.
- One section visible at a time. No long-scroll.
### Phase 5 — Critical-path simplification.
- Dictation page: header + transcript surface + action rail + empty state. No cockpit furniture.
- Files, Tasks, History migrated to the shared page skeleton (left nav, header, optional toolbar, primary work surface, optional right drawer, status row).
- Empty states speak on all four pages.
- Persona-test gates for Pawel, Simone, Chris, Ron at this phase.
### Phase 6 — Icon and wordmark integration.
- Real Lumotia wordmark + mark lifted from brand-proposal v1 colophon. Replaces the placeholder swirl.
- Surfaces: window icon (.ico, .icns, multi-size .png), splash, About modal, empty-state anchor, status-pill leading glyph for "Ready".
- Removes any remaining Magnotia / Wyrdnote / Kon-era assets.
### Phase 7 — Motion audit. (final v0.3 polish)
- Inventory every animation, transition and decorative motion currently in the app.
- Keep: recording-active heartbeat, loading spinner, success / failure feedback.
- Strip: decorative pulse, animated background, sliding panels, attention shimmer.
- `prefers-reduced-motion` reducer set at the root selector for quietware (already in tokens CSS).
### Phase 8 — Promote to default. (post-release decision)
- Flip `<html data-design="quietware">` to be the default; remove the flag.
- Either lands as a major release (v1.0) or stays opt-in indefinitely.
- This decision is deferred to after Phase 6 user testing.
---
## Phase log
### Phase 1 — Tokens. Landed 2026-05-15.
- `src/design-system/v0.3-quietware-tokens.css` written. 5.7 KB.
- Three WOFF2 fonts added at `src/fonts/`: `work-sans-variable.woff2`, `work-sans-italic-variable.woff2`, `young-serif.woff2`. 287 KB total.
- `src/app.css` imports the new tokens file directly after `@import "tailwindcss"`.
- Inert without `data-design="quietware"` on `<html>`. v0.2 surface unaffected.
- Verified by visual inspection. Manual activation via dev tools toggling the attribute.
- Palette iterated three times this session (brand-as-semantic → cobalt-pegged square → color.adobe.com primaries). Final values locked in commit on amendment.
### Phase 2 — Build flag wiring. Landed 2026-05-15.
- `src/routes/+layout.svelte` extended with a `$effect` block that reads `import.meta.env.VITE_LUMOTIA_QUIETWARE` at runtime and sets `<html data-design="quietware">` when the flag is `"1"`.
- Hot-reload safety: if the env var is unset between dev rebuilds, the attribute is cleared.
- Activation: `VITE_LUMOTIA_QUIETWARE=1 npm run dev` (or `npm run build`) lights up the quietware tokens. Without the env var, app renders v0.2 unchanged.
- Combine with `data-theme="light"` and `data-contrast="high"` (already wired by v0.2) to reach the light and high-contrast quietware modes.
- No new dependencies. No bundle-size impact in the off path.
### Phase 3 — Status grammar primitives. Landed 2026-05-15.
Architectural finding: both `LumotiaStatusPill` and `LumotiaNotice` already shipped in v0.2 Phase 5. Phase 3 became an audit-and-adapt task rather than a new-component build.
- `LumotiaStatusPill` ([src/lib/components/StatusPill.svelte](../../src/lib/components/StatusPill.svelte)) audited. Pattern is already accessibility-correct: neutral pill background + neutral label text + role colour confined to a 6×6 px dot. Colour is supplementary, label is always perceivable. Works unchanged across all three quietware modes. No changes shipped.
- `LumotiaNotice` ([src/lib/ui/LumotiaNotice.svelte](../../src/lib/ui/LumotiaNotice.svelte)) refactored to the left-bar accent pattern. Old version put the role colour on the icon + outline; in quietware light mode that rendered a bright `#FFCD00` caution icon faded against cream paper. New version places the role signal on a 4-px solid left border (visible at any contrast level), with the rest of the surround as a soft tone-tinted background plus subtle neutral outer border. Icon, title and body text all use `--color-text`. Matches Material "banner with leading accent" and IBM Carbon "inline notification" guidance. ARIA semantics (`role="alert"` for danger, `role="status"` for the rest) preserved.
- Design-system-v2 preview route already imports `LumotiaNotice` and `LumotiaStatusPill`. The updated Notice renders correctly there with the existing preview content; no additional preview wiring needed.
- All four tones (info / caution / danger / success) verified by the pattern itself: the visible signal is the left bar, which is `border-l-{tone}` at 100% opacity, working at any colour intensity. Caution remains a fill-only convention on cream by design.
---
## Regression diary
Empty. Update inline as findings emerge per phase.
---
## References
- Source brief: `inputs/inbox/2026-05-15-lumotia-colour-layout-changes.md`.
- Palette refinement round 1 (brand-as-semantic): `inputs/inbox/2026-05-15-re-lumotia-v03-renders-revised-palette-typography-.md`.
- Palette refinement round 2 (cobalt-square peg): chat decision 2026-05-15.
- Palette refinement round 3 (color.adobe.com primaries): `inputs/inbox/2026-05-15-re-lumotia-v03-phase-1-landed-cobalt-pegged-square.md` + attached `2.jpeg`. Locked.
- W3C COGA: `https://www.w3.org/TR/coga-usable/`.
- WCAG 2.2 Understanding docs: `https://www.w3.org/WAI/WCAG22/Understanding/`.
- HMRC accessibility personas: `https://personas-prototype.herokuapp.com/`.
- DfE accessibility tools manual: `https://accessibility.education.gov.uk/tools-testing/tools`.
- v0.2 release doc: `docs/release/v0.2-frontend-overhaul.md` (predecessor; reference patterns).