Issue #46: Accent colour — accent (tint) on /operator/personalization #59

Merged
EduarD3V merged 9 commits from issue/46-accent-colour into agent-develop 2026-10-07 16:50:55 +02:00
Collaborator

New page /operator/personalization where the operator picks the console accent — the tint applied to the brand token. The existing Settings appearance control keeps showing system / light / dark, unchanged.

What ships

  • dashboard/src/app.css — --accent-hue: 260 in :root; the hue of five literals is now var(--accent-hue): light --primary, --accent, --sidebar-ring; dark --primary, --accent. Lightness and chroma stay in the stylesheet per theme. --ring, --info, --chart-1, --sidebar-primary, the soft wash, focus rings, and links all derive from --primary, so they follow for free.
  • dashboard/src/lib/theme.ts — ACCENT_STORAGE_KEY, ACCENT_HUE_TOKEN, DEFAULT_ACCENT_HUE, ACCENT_PALETTE (7 anchors), parseAccentHue, readStoredAccentHue, persistAccentHue, applyAccentHue, the accentHue store, setAccentHue.
  • dashboard/src/app.html — the boot IIFE also reads gotoi-accent and writes --accent-hue before first paint, so a reload never flashes the wrong tint.
  • dashboard/src/routes/operator/personalization/+page.svelte — new page: seven tint anchors with swatches, Reset to Indigo, a live preview (primary / outline / link / soft wash), and a pointer to Settings › Appearance for the theme.
  • Wire-up: nav.ts (Operator item + palette icon), page-help.ts, destinations.ts, scripts/e2e/nav_selenium.py.
  • docs/use-cases/frontend/UC-FE-99-accent-personalization.md — new UC; related: + ## Related added bidirectionally to UC-FE-08, UC-FE-80, UC-FE-85; indexed in docs/use-cases/README.md.

Rebased onto develop

Issue #44 landed UC-FE-98-hidden-system-plans on develop after this branch was cut, taking the id
UC-FE-98. The branch is rebased onto develop and the accent UC renumbered to UC-FE-99 — id, file
name, related: backlinks and the test citations all move together. Upstream UC-FE-98 (system plans)
is untouched.

Design

One hue custom property, not a JS palette. The tint is --accent-hue on document.documentElement; the CSS cascade does the rest and no JS knows the palette. Default 260 reproduces the shipped Polar Indigo exactly.

Consequence, recorded: dark --primary hue moved 262 → 260 (2°, imperceptible) so both themes share one knob.

Contrast measured in the running browser (oklch → sRGB → WCAG relative luminance) on the rendered --primary/--primary-foreground pair: light bottoms at 5.06:1 (Emerald, the worst anchor); dark spans 8.66–9.44:1. Every anchor clears AA with margin.

Verification

  • python3 docs/use-cases/_check.py — pass (356 UC files, all conform)
  • python3 scripts/check-ai-headers.py — pass (572 ok, 0 missing, 0 malformed)
  • python3 scripts/check-type-mirror.py — pass (exit 0)
  • cd dashboard && bun run test — pass (16 files, 249 tests)
  • cd dashboard && bun run check — pass (2346 files, 0 errors, 7 pre-existing warnings)
  • cd dashboard && bun run build — pass (adapter-node, exit 0)
  • rg -n 'Showing lines' — only pre-existing doc quotes; no source file
  • cd agent && gofmt -l agent — empty (no agent file touched)

Browser smoke against a real Chromium and a live middleware: fresh browser shows no inline override and --primary: oklch(0.52 0.12 260) with Reset disabled; click Azure → inline 230, computed oklch(0.52 0.12 230); reload keeps 230 with no flash and no console or hydration errors; Reset removes the inline property; dark theme keeps its own lightness and chroma (oklch(0.76 0.10 230)). Settings still offers System / Light / Dark.

Known pre-existing failure (not from this branch)

cd middleware && bun test is red on the branch base with zero middleware files in this diff (git diff --name-only <base> HEAD -- middleware is empty). UC-MW-19 fails Expected: 201 / Received: 500 because the gitignored middleware/data/plans/restart-nginx.git left on disk makes POST /plans {id:'restart-nginx'} hit an already-initialized repo (nothing to commit). Removing middleware/data/ → 10 pass / 0 fail, but the run recreates it, so the next run is red again. Reproduces on the untouched base. Not weakened or skipped.

Assumptions

  • /operator/* is instance-operator gated, so the page inherits that gate. A move to /settings/personalization is one line if it should be per-user instead.
  • "the modal keeps showing system,dark and light" read as the Settings appearance control staying exactly as shipped.
  • The accent is browser-local (localStorage, same as gotoi-theme), not per-account and not synced.
  • Anchors: Indigo, Azure, Teal, Emerald, Amber, Rose, Violet. No free-hue slider — a range control needs a native <input type="range"> the installed component set does not have.

Refs #46

New page `/operator/personalization` where the operator picks the console accent — the tint applied to the brand token. The existing Settings appearance control keeps showing system / light / dark, unchanged. ## What ships - **`dashboard/src/app.css`** — `--accent-hue: 260` in `:root`; the hue of five literals is now `var(--accent-hue)`: light `--primary`, `--accent`, `--sidebar-ring`; dark `--primary`, `--accent`. Lightness and chroma stay in the stylesheet per theme. `--ring`, `--info`, `--chart-1`, `--sidebar-primary`, the soft wash, focus rings, and links all derive from `--primary`, so they follow for free. - **`dashboard/src/lib/theme.ts`** — `ACCENT_STORAGE_KEY`, `ACCENT_HUE_TOKEN`, `DEFAULT_ACCENT_HUE`, `ACCENT_PALETTE` (7 anchors), `parseAccentHue`, `readStoredAccentHue`, `persistAccentHue`, `applyAccentHue`, the `accentHue` store, `setAccentHue`. - **`dashboard/src/app.html`** — the boot IIFE also reads `gotoi-accent` and writes `--accent-hue` before first paint, so a reload never flashes the wrong tint. - **`dashboard/src/routes/operator/personalization/+page.svelte`** — new page: seven tint anchors with swatches, Reset to Indigo, a live preview (primary / outline / link / soft wash), and a pointer to Settings › Appearance for the theme. - Wire-up: `nav.ts` (Operator item + `palette` icon), `page-help.ts`, `destinations.ts`, `scripts/e2e/nav_selenium.py`. - **`docs/use-cases/frontend/UC-FE-99-accent-personalization.md`** — new UC; `related:` + `## Related` added bidirectionally to `UC-FE-08`, `UC-FE-80`, `UC-FE-85`; indexed in `docs/use-cases/README.md`. ## Rebased onto develop Issue #44 landed `UC-FE-98-hidden-system-plans` on `develop` after this branch was cut, taking the id `UC-FE-98`. The branch is rebased onto `develop` and the accent UC renumbered to **UC-FE-99** — id, file name, `related:` backlinks and the test citations all move together. Upstream `UC-FE-98` (system plans) is untouched. ## Design One hue custom property, not a JS palette. The tint is `--accent-hue` on `document.documentElement`; the CSS cascade does the rest and no JS knows the palette. Default 260 reproduces the shipped Polar Indigo exactly. Consequence, recorded: dark `--primary` hue moved **262 → 260** (2°, imperceptible) so both themes share one knob. Contrast measured in the running browser (oklch → sRGB → WCAG relative luminance) on the rendered `--primary`/`--primary-foreground` pair: light bottoms at 5.06:1 (Emerald, the worst anchor); dark spans 8.66–9.44:1. Every anchor clears AA with margin. ## Verification - `python3 docs/use-cases/_check.py` — pass (356 UC files, all conform) - `python3 scripts/check-ai-headers.py` — pass (572 ok, 0 missing, 0 malformed) - `python3 scripts/check-type-mirror.py` — pass (exit 0) - `cd dashboard && bun run test` — pass (16 files, 249 tests) - `cd dashboard && bun run check` — pass (2346 files, 0 errors, 7 pre-existing warnings) - `cd dashboard && bun run build` — pass (adapter-node, exit 0) - `rg -n 'Showing lines'` — only pre-existing doc quotes; no source file - `cd agent && gofmt -l agent` — empty (no agent file touched) Browser smoke against a real Chromium and a live middleware: fresh browser shows no inline override and `--primary: oklch(0.52 0.12 260)` with Reset disabled; click Azure → inline `230`, computed `oklch(0.52 0.12 230)`; reload keeps 230 with no flash and no console or hydration errors; Reset removes the inline property; dark theme keeps its own lightness and chroma (`oklch(0.76 0.10 230)`). Settings still offers System / Light / Dark. ## Known pre-existing failure (not from this branch) `cd middleware && bun test` is red on the branch base with **zero** middleware files in this diff (`git diff --name-only <base> HEAD -- middleware` is empty). `UC-MW-19` fails `Expected: 201 / Received: 500` because the gitignored `middleware/data/plans/restart-nginx.git` left on disk makes `POST /plans {id:'restart-nginx'}` hit an already-initialized repo (`nothing to commit`). Removing `middleware/data/` → 10 pass / 0 fail, but the run recreates it, so the next run is red again. Reproduces on the untouched base. Not weakened or skipped. ## Assumptions - `/operator/*` is instance-operator gated, so the page inherits that gate. A move to `/settings/personalization` is one line if it should be per-user instead. - "the modal keeps showing system,dark and light" read as the Settings appearance control staying exactly as shipped. - The accent is browser-local (`localStorage`, same as `gotoi-theme`), not per-account and not synced. - Anchors: Indigo, Azure, Teal, Emerald, Amber, Rose, Violet. No free-hue slider — a range control needs a native `<input type="range">` the installed component set does not have. Refs #46
app.css derives --primary/--accent/--sidebar-ring from --accent-hue (UC-FE-98), so a
single hue tints the whole console without a second brand colour. theme.ts owns the
storage key, palette, and applier; app.html applies the stored hue before first paint.

Refs #46
New page picks one of seven tint anchors; nav, page help, destinations, and the
selenium walk carry the route. Tests pin the palette, the storage round-trip, the
app.css derivation, and the new href order. Refs #46
Refs #46
The active nav item is styled from --muted, not --primary, so claiming it was wrong.

Refs #46
Refs #46
dashboard: describe the personalization page header precisely
Some checks failed
agent-guards / test-tampering (pull_request) Failing after 32s
CI and agent release / check-docs (pull_request) Successful in 31s
CI and agent release / test-agent (pull_request) Successful in 1m46s
CI and agent release / test-dashboard (pull_request) Successful in 2m42s
CI and agent release / build (pull_request) Has been cancelled
CI and agent release / release (pull_request) Has been cancelled
CI and agent release / publish-images (pull_request) Has been cancelled
CI and agent release / test-middleware (pull_request) Has been cancelled
37da458929
Refs #46
EduarD3V force-pushed issue/46-accent-colour from 37da458929
Some checks failed
agent-guards / test-tampering (pull_request) Failing after 32s
CI and agent release / check-docs (pull_request) Successful in 31s
CI and agent release / test-agent (pull_request) Successful in 1m46s
CI and agent release / test-dashboard (pull_request) Successful in 2m42s
CI and agent release / build (pull_request) Has been cancelled
CI and agent release / release (pull_request) Has been cancelled
CI and agent release / publish-images (pull_request) Has been cancelled
CI and agent release / test-middleware (pull_request) Has been cancelled
to 75347a275b
Some checks failed
agent-guards / test-tampering (pull_request) Failing after 33s
CI and agent release / check-docs (pull_request) Successful in 29s
CI and agent release / test-agent (pull_request) Successful in 1m45s
CI and agent release / test-dashboard (pull_request) Successful in 2m48s
CI and agent release / test-middleware (pull_request) Successful in 9m4s
CI and agent release / build (pull_request) Has been skipped
CI and agent release / release (pull_request) Has been skipped
CI and agent release / publish-images (pull_request) Has been skipped
2026-10-07 16:16:44 +02:00
Compare
gotoi-agent changed target branch from develop to agent-develop 2026-10-07 16:19:08 +02:00
check-test-tampering.py flags a toBeLessThan range matcher next to a removed
toEqual in the same file as a loosened assertion; the same invariant reads
strictly through one toBe(true). Refs #46
EduarD3V merged commit fe0537ff88 into agent-develop 2026-10-07 16:50:55 +02:00
Sign in to join this conversation.
No description provided.