Problem
Task/agent status is expressed through four parallel color/label systems with hardcoded hex values scattered across files — and the colors fail contrast on the light theme because they bypass the token system entirely.
Fragmentation:
- Two overlapping enums:
TaskDotStatus ('busy'|'waiting'|'ready'|'review') and TaskAttentionState ('idle'|'active'|'needs_input'|'error'|'ready'|'review') — src/store/taskStatus.ts:110-111. StatusDot.tsx:6-15 merges them with attention overriding status; the result is that "agent working" renders as muted gray (busy) or accent (active) depending on which code path computed it.
- Hardcoded status hexes outside the theme:
#c084fc and #e5a800 in StatusDot.tsx:10,12,25; #c084fc duplicated again in Sidebar.tsx:68.
TaskStepsSection.tsx:11-15 defines five more phase colors (#fb923c, #60a5fa, #c084fc, #e5a800, #f87171).
SubTaskStrip.tsx invents its own tone system with #f87171 (:101) and #22c55e (:157,168) plus ✓/✕ glyphs instead of StatusDot.
TaskTitleBar.tsx:39-66 re-expresses the same landing states as text badges with different labels; PR/CI checks use a fourth dot+spinner vocabulary (TaskBranchInfoBar.tsx:125-181, TaskTitleBar.tsx:262-325).
Contrast & accessibility:
- On the islands-light preset (white
--bg-elevated, styles.css:445): #e5a800 = 2.11:1, #c084fc = 2.64:1 — both fail WCAG 1.4.11 (3:1 for non-text UI indicators). Status dots are the app's primary signal and are near-invisible on the light theme.
StatusDot is a bare <span> with only title= — not focusable, no role="img"/aria-label (StatusDot.tsx:51-63), and ready/review/waiting differ only by hue (indistinguishable under deuteranopia).
Proposed fix
From a full design/UX audit (2026-07-07); adversarially verified, contrast ratios recomputed. Line numbers as of b342bbd (v1.12.0).
Problem
Task/agent status is expressed through four parallel color/label systems with hardcoded hex values scattered across files — and the colors fail contrast on the light theme because they bypass the token system entirely.
Fragmentation:
TaskDotStatus('busy'|'waiting'|'ready'|'review') andTaskAttentionState('idle'|'active'|'needs_input'|'error'|'ready'|'review') —src/store/taskStatus.ts:110-111.StatusDot.tsx:6-15merges them with attention overriding status; the result is that "agent working" renders as muted gray (busy) or accent (active) depending on which code path computed it.#c084fcand#e5a800inStatusDot.tsx:10,12,25;#c084fcduplicated again inSidebar.tsx:68.TaskStepsSection.tsx:11-15defines five more phase colors (#fb923c,#60a5fa,#c084fc,#e5a800,#f87171).SubTaskStrip.tsxinvents its own tone system with#f87171(:101) and#22c55e(:157,168) plus✓/✕glyphs instead of StatusDot.TaskTitleBar.tsx:39-66re-expresses the same landing states as text badges with different labels; PR/CI checks use a fourth dot+spinner vocabulary (TaskBranchInfoBar.tsx:125-181,TaskTitleBar.tsx:262-325).Contrast & accessibility:
--bg-elevated,styles.css:445):#e5a800= 2.11:1,#c084fc= 2.64:1 — both fail WCAG 1.4.11 (3:1 for non-text UI indicators). Status dots are the app's primary signal and are near-invisible on the light theme.StatusDotis a bare<span>with onlytitle=— not focusable, norole="img"/aria-label(StatusDot.tsx:51-63), and ready/review/waiting differ only by hue (indistinguishable under deuteranopia).Proposed fix
--status-*theme token per state, with a light-preset override; delete the hardcoded hexes. This also makes status themable by the custom-theme feature, which currently can't reach these colors.role="img" aria-label={getDotTooltip(…)}on StatusDot (one line), and a secondary non-color channel (dot shape or a short text badge) for ready/review/waiting.From a full design/UX audit (2026-07-07); adversarially verified, contrast ratios recomputed. Line numbers as of b342bbd (v1.12.0).