feat(ui): orch theme — third palette + 5-click easter egg + 2s unlock freeze#106
Merged
Conversation
Extends the dual-theme system (PRD-015 / RFC-014) with a third opt-in palette `orch`: pure-black surfaces (`--bg: #000`) and lavender accent (`--accent: #a78bfa`). Toggle in the health bar gains a fourth position alongside Auto / Light / Dark; `auto` mode stays binary and never resolves to `orch`. Pre-paint inline script accepts the new mode synchronously, so first-paint is FOUC-free for users who saved it. The change is a pure token-swap — every CSS-var defined under `:root[data-theme='dark']` is mirrored under `:root[data-theme='orch']`, so no component-level code changes were required. Verified via svelte-check (0/0 errors/warnings across 1047 files), token-name diff (empty modulo intentionally-shared `--font-*` / `--dot-grid-*`), and production build round-trip (compiled `_layout.css` carries all three selectors and the lavender literal). FG/BG contrast 16.58:1 (AAA). Refs: PRD-023, EVID-028 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UX shape change for the orch theme (PRD-023 v2):
- The visible health-bar toggle now stays at three positions
(Auto / Light / Dark). Orch becomes a 4th visible item only
after the user clicks Dark five times in a row — a hidden
Easter egg. Counter resets when any non-Dark item is clicked.
- Once Orch is active, clicking it (deselect) bounces back to
Auto. Clicking any active item never leaves the toggle
visually empty: a remount tick is bumped on every empty
emit from bits-ui so the controlled `value` prop re-pins
the visual state. Spec invariant: 100% always some pressed
item.
- Two race conditions tamed:
1. bits-ui ToggleGroup fires onValueChange("dark") AFTER
our click-delegation handler has already advanced mode
to "orch" on the 5th dark click. Sentinel
`justUnlockedOrch` swallows that single follow-up.
2. bits-ui's internal `data-state` desyncs from a
controlled `value` when the user re-clicks an active
item. `{#key toggleRemountTick + ":" + items.length}`
forces a fresh ToggleGroup mount so the visual re-pins.
Palette softened per user feedback ("цвета слишком
контрастные") to match Orchestra's marketing references:
foreground stepping compressed (`--fg` `#fafafa` →
`#d6cdf2`, `--fg-1` `#e8e8ed` → `#b3acc8`, etc.), accent
moved to a paler lavender (`#a78bfa` → `#b9a8ff`), and
edge / canvas / good-bad tokens dimmed proportionally.
F/B contrast `--fg-1` on `--bg-1` ≈ 9.7:1 — comfortably
above WCAG AAA, but visually softer than the previous
16.6:1.
Verified in browser via dev server (5174):
- 5 Dark clicks → orch active, Orch button appears + pressed
- Click active Orch → Auto active, orch button gone
- Click active Auto / active Light → stays / falls back to Auto
- Theme persists through reload via inline pre-paint script
Refs: PRD-023, EVID-028
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Once Orch becomes visible (5th consecutive Dark click), all theme toggle items go disabled for ORCH_LOCK_MS = 2000ms so accidental follow-up clicks (the user keeps mashing Dark beyond the 5th unlock click) cannot immediately bounce out of orch. Disabled state propagates through bits-ui via the existing `disabled` prop on ToggleGroupItem; the click-delegation handler also early-returns during the lock as a defensive belt-and-braces. Refs: PRD-023 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a third theme palette
orch(Orchestra-inspired pure-black + muted lavender) alongside the existingdarkandlightpalettes, hidden behind a 5-consecutive-Dark-clicks Easter egg with a 2s post-unlock toggle freeze.--bg #000,--accent #b9a8ff, foreground stepped from#d6cdf2→#2e2b36. Lower contrast thandarkper design references; AAA on--fg-1/--bg-1.Why
PRD-023 / EVID-028. Existing dual-theme system (PRD-015 / RFC-014) only exposed warm
dark(#ff5a1faccent) and creamlight. Adds a cool true-black palette for OLED users and long-session reviewers, gated behind an Easter egg per user direction.Test plan
cd template && npm run check— 0 errors / 0 warnings (1047 files)cd template && npm run build— built successfully; orch palette + lavender accent present in production CSSFiles
template/src/app/styles/app.css—:root[data-theme='orch']palette block (every dark-defined token mirrored, dimmer/cooler values)template/src/shared/lib/theme.svelte.ts—ThemeMode/ThemeEffectivewidened to include'orch'template/src/app.html— pre-paint script accepts'orch'template/src/widgets/health-bar/ui/HealthBar.svelte— 5-click streak, 2s lock, deselect-to-auto, remount-tick visual re-pin.forgeplan/prds/PRD-023-...md+.forgeplan/evidence/EVID-028-...md— Forgeplan artifacts (R_eff = 1.0)Refs: PRD-023, EVID-028
🤖 Generated with Claude Code