Voice & Persona
Persona Identity Refresh
The header overflowed on a real phone and hid the menu — collapse the redundant persona chip + status pill into one persona-led control.
Situation
On a real phone the Round B header overflows: the MALLORY_ wordmark, PersonaChip, StatusPill, and menu exceed ~390px, clipping the status pill and pushing the menu unreachable. The root cause is redundancy — persona and mode encode the same state twice.
Dropping the wordmark also leaves the threshold and cleared screen as the app's only wordmark surfaces, so this round makes the whole identity coherent and persona-led rather than just patching the overflow.
Key decisions
Header = persona + status ring + menu
Drop the <h1>Mallory_</h1> wordmark; collapse the persona chip and status pill into one tappable persona control plus a restored status ring.
Persona control design
Badge (shape+fill) + Title Case name + a per-persona-coloured _ caret + a mode subtitle that hides the activity when it's off.
Status ring restored
The pre-#58 ring — grey quiet, oxblood fill on attention, pulse on loading — a circle shape distinct from the squircle badge, both opening the same sheet.
Persona switcher maps to the existing mode override
Mallory ⇄ Moneypenny plus a "Talk to Q →" shortcut, living in the status sheet; no new state, auto-expires at 04:00 like any override.
Theme-aware persona accents
Each persona gains a darker, AA-clearing light-theme accent alongside its existing dark accent; the caret always carries the active persona's colour.
Architecture
Web-only refresh building on Round B's persona system and Wave 6 modes — no Worker/DB changes.
accentLight; resolves per-theme CSS custom properties for the threaded accent.PersonaChip.svelte into a header block: badge + name + caret + mode subtitle, aria-label, 44px target.StatusPill in the header.+page.svelte removes the wordmark; persona control (left), status ring (right), menu — both open StatusSheet.StatusSheet.svelte; personaOverride(personaId, currentMode) pure mapping to the mode override.personaGreeting.ts — pickGreeting(persona, mode, now), a persona-voiced, deterministic-rotation replacement for the generic time-greeting.Risks & guardrails
Light-theme contrast
Each persona's new light accent must independently clear AA on paper background (#f4f1ea) — verified per-persona in the spec table.
Coarse override mapping
The switcher's persona→mode mapping is a canonical v1 approximation (e.g. Mallory always restores 'working'); finer mapping is explicitly deferred.
Dead-code cleanup completeness
StatusPill.svelte and single-hex --persona assumptions must be fully removed, not just bypassed — requires a grep-first check for other consumers.
Delivery
P1 — Pure helpers + theme-aware accents
Accent tokens, mode-subtitle helper, persona-override/greeting helpers, with tests.
P2 — StatusRing + persona control
Build the ring and evolve the chip into the header persona block.
P3 — Header restructure
Drop the wordmark, wire control + ring to the sheet.
P4 — Switcher in StatusSheet
Persona chips + Talk-to-Q link.
P5 — Cleared-screen persona greeting
Wire pickGreeting into the welcome.
P6 — Cleanup + a11y/design pass
Remove StatusPill and dead CSS, contrast/reduced-motion pass, docs.
Out of scope
docs/superpowers/specs/2026-06-20-persona-identity-refresh-design.mdplan ·
docs/superpowers/plans/2026-06-20-persona-identity-refresh.md