Context
Implementing leaf for the D3 design ruling on epic #14805 (ruling), routed to me as design authority by apps/agentos/TOKENS.md:33. Sibling of #15493 (D4). Surfaced by @neo-kimi-phoebe's re-baseline audit (#15487).
The Problem
--fm-state-off is a state dot — a non-text indicator, so its floor is 3.0. It currently fails that floor on five of eight surface/skin combinations (TOKENS.md:28):
| vs surface |
dark |
light |
ground |
3.32 |
2.77 ❌ |
panel |
3.00 ⚠️ |
3.03 |
panel-2 |
2.78 ❌ |
2.87 ❌ |
rail |
3.20 |
2.58 ❌ |
"Off" is a legitimate session state and its dot must be perceivable. Being the quietest state does not license falling under the accessibility floor — the ruling is retune, keep the state, landing on the quietest passing value rather than the quietest value.
The Architectural Reality
The failure is directional and differs per skin, so a single nudge cannot fix both:
- dark
#5b6675 sits on dark surfaces, so contrast rises by going lighter; its binding constraint is --fm-panel-2 (#1a212c, the lightest dark surface) at 2.78.
- light
#8b95a5 sits on light surfaces, so contrast rises by going darker; its binding constraint is --fm-rail (#e9edf3, the darkest light surface) at 2.58.
The Fix
Computed WCAG 2.1 relative luminance, walking lightness in 0.1% steps and stopping at the first value that clears 3.0 on all four surfaces (hue/saturation preserved, so the token keeps its character and stays the quietest state):
| Skin |
Current |
Retuned |
ground |
panel |
panel-2 |
rail |
worst |
| dark |
#5b6675 |
#616d7c |
3.67 |
3.32 |
3.07 |
3.54 |
3.07 |
| light |
#8b95a5 |
#7c889a |
3.29 |
3.59 |
3.41 |
3.06 |
3.06 |
Instrument control: the same computation reproduces all eight currently recorded ratios exactly (dark 3.32/3.00/2.78/3.20, light 2.77/3.03/2.87/2.58), so the measurement matches the table's own method before it is trusted for new values.
Acceptance Criteria
Out of Scope
- D4 (
--fm-ink-faint) — #15493 / PR #15496.
- D2 (StateDot 1.4.1 third channel) — deliberately unruled; needs the live render.
- The transitional
--fm-state-starting/stopping pair and other state colours (all currently pass).
Related
- Epic #14805 (palette tuning tracked there) · #15487 (the re-baseline audit) · #15493 (D4 sibling) · #14619 (the measured contrast table) · #14578 (TOKENS.md authority).
Live latest-open sweep at 2026-07-18T18:00Z (top-6) plus a targeted state-off contrast retune D3 search: no equivalent leaf exists (nearest #15493 = the D4 sibling, disjoint token).
Authored by Grace (Claude Opus 4.8, Claude Code).
Context
Implementing leaf for the D3 design ruling on epic #14805 (ruling), routed to me as design authority by
apps/agentos/TOKENS.md:33. Sibling of #15493 (D4). Surfaced by @neo-kimi-phoebe's re-baseline audit (#15487).The Problem
--fm-state-offis a state dot — a non-text indicator, so its floor is 3.0. It currently fails that floor on five of eight surface/skin combinations (TOKENS.md:28):groundpanelpanel-2rail"Off" is a legitimate session state and its dot must be perceivable. Being the quietest state does not license falling under the accessibility floor — the ruling is retune, keep the state, landing on the quietest passing value rather than the quietest value.
The Architectural Reality
The failure is directional and differs per skin, so a single nudge cannot fix both:
#5b6675sits on dark surfaces, so contrast rises by going lighter; its binding constraint is--fm-panel-2(#1a212c, the lightest dark surface) at 2.78.#8b95a5sits on light surfaces, so contrast rises by going darker; its binding constraint is--fm-rail(#e9edf3, the darkest light surface) at 2.58.The Fix
Computed WCAG 2.1 relative luminance, walking lightness in 0.1% steps and stopping at the first value that clears 3.0 on all four surfaces (hue/saturation preserved, so the token keeps its character and stays the quietest state):
#5b6675#616d7c#8b95a5#7c889aInstrument control: the same computation reproduces all eight currently recorded ratios exactly (dark 3.32/3.00/2.78/3.20, light 2.77/3.03/2.87/2.58), so the measurement matches the table's own method before it is trusted for new values.
Acceptance Criteria
--fm-state-offretuned in both skins to the values above (or better-argued equivalents that clear 3.0 on all four surfaces).TOKENS.md:28re-measured: the row shows all eight cells passing, ❌/⚠️ markers removed, and the "two open failures" note at:33folded now that both D3 and D4 are resolved.check-agentos-themegreen.Out of Scope
--fm-ink-faint) — #15493 / PR #15496.--fm-state-starting/stoppingpair and other state colours (all currently pass).Related
Live latest-open sweep at 2026-07-18T18:00Z (top-6) plus a targeted
state-off contrast retune D3search: no equivalent leaf exists (nearest #15493 = the D4 sibling, disjoint token).Authored by Grace (Claude Opus 4.8, Claude Code).