feat(tokens): widen the palette to twenty-one roles #207

Merged
nalum merged 1 commit from feat/tokens-warning-role into main 2026-08-26 18:33:38 +00:00
Owner

Closes #170.

Nine roles per mode could not express the surfaces the jobs and calendar
redesigns are built from: the fill behind an in-place edit box, a sheet's
footer, an unticked checkbox, an invalid row's ring, a destructive button,
or a late job.

Twelve new roles, the original nine untouched in name and meaning:
surface-raised, surface-sunken, ink-muted, border, border-strong,
error, error-surface, destructive, on-destructive, warning,
on-warning, on-celebrate.

warning is its own role and never an alias of celebrate. celebrate
means reward; a token with two meanings is the fault the design rejects
elsewhere. It is amber rather than red because red means destruction here,
and a late job is still a job you can finish in ten seconds. The ⚠ glyph
was already in the bundled symbol subset, so no font work.

456 values authored per theme, per mode — derived from each theme's own
hues rather than one grey reused nineteen times. The contrast gate grew
with them: sixteen hard pairs per variant per mode, including
border-strong against the 3:1 non-text floor, since a checkbox outline is
a mark and not text. The 4.5:1 gate was not weakened and no role is exempt.

Two judgment calls worth an eye: cvd-red-teal's warning is burnt orange,
because amber sits on the exact blue-yellow axis that theme exists to
avoid; and mono separates warning from error by lightness alone, leaning
on the glyph and the word.

Nothing consumes the new roles yet — this ticket adds vocabulary. Follow-up
#202: custom themes still override only the original nine.

🤖 Generated with Claude Code

Closes #170. Nine roles per mode could not express the surfaces the jobs and calendar redesigns are built from: the fill behind an in-place edit box, a sheet's footer, an unticked checkbox, an invalid row's ring, a destructive button, or a late job. Twelve new roles, the original nine untouched in name and meaning: `surface-raised`, `surface-sunken`, `ink-muted`, `border`, `border-strong`, `error`, `error-surface`, `destructive`, `on-destructive`, `warning`, `on-warning`, `on-celebrate`. `warning` is its own role and never an alias of `celebrate`. `celebrate` means reward; a token with two meanings is the fault the design rejects elsewhere. It is amber rather than red because red means destruction here, and a late job is still a job you can finish in ten seconds. The ⚠ glyph was already in the bundled symbol subset, so no font work. 456 values authored per theme, per mode — derived from each theme's own hues rather than one grey reused nineteen times. The contrast gate grew with them: sixteen hard pairs per variant per mode, including `border-strong` against the 3:1 non-text floor, since a checkbox outline is a mark and not text. The 4.5:1 gate was not weakened and no role is exempt. Two judgment calls worth an eye: `cvd-red-teal`'s warning is burnt orange, because amber sits on the exact blue-yellow axis that theme exists to avoid; and `mono` separates warning from error by lightness alone, leaning on the glyph and the word. Nothing consumes the new roles yet — this ticket adds vocabulary. Follow-up #202: custom themes still override only the original nine. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(tokens): widen the palette to twenty-one roles
All checks were successful
check / commits (pull_request) Successful in 6s
check / go (pull_request) Successful in 2m47s
android / build (pull_request) Successful in 6m33s
check / web (pull_request) Successful in 4m25s
check / report (pull_request) Successful in 4s
android / report (pull_request) Successful in 4s
1a073fbc2b
The nine roles could name a page, a card, two inks, an accent and a red,
and nothing else. Everything the jobs redesign asks for below that level
— the fill behind an in-place edit box, a sheet's footer, an unselected
chip outline, an unticked checkbox, body text a step under the title, an
invalid row and its ring, a delete button's fill — had no token to
resolve through, so it would have arrived as hard-coded hex in
components. Twelve roles close that gap; nothing consumes them yet.

warning is its own role rather than a second meaning for celebrate.
celebrate already means reward, and a late job is neither a reward nor a
failure: amber because red is destruction here, and a late job is still
a job you can finish in ten seconds. Sharing one token would have put
two meanings on one colour, which is the fault the design rejects
elsewhere.

Values are derived per theme rather than picked once and repeated:
surfaces step off the card and the page in Oklab lightness, borrowing
the page's tint where a white card has no hue of its own; borders walk
the theme's own hairline toward its ink; error and destructive come from
the theme's red, destructive sunk deep enough to carry near-white ink;
warning comes from the theme's gold turned toward orange, from an amber
anchor where the gold is not warm, from the theme's own red-orange in
the tritanopia theme where amber sits on the axis that theme exists to
avoid, and from luminance alone in the achromatic theme. Direction gives
way to the AA floor: where a theme's ink has no headroom left, a step
goes the other way rather than dropping below 4.5.

The gate grows with the vocabulary — every ink-on-fill and state-ink
pair is hard-checked at 4.5, and border-strong against card at the 3:1
non-text floor, so no new role ships unaudited.

Test report

Suite Tests Result Skipped
Unit 1410 ✅ pass 1
Integration 113 ✅ pass —

Coverage: 26.9%

Updated by the check workflow · commit 87e14d060a

<!-- ci-test-report --> ## Test report | Suite | Tests | Result | Skipped | | --- | --: | --- | --: | | Unit | 1410 | ✅ pass | 1 | | Integration | 113 | ✅ pass | — | **Coverage:** 26.9% <sub>Updated by the check workflow · commit 87e14d060aab364a019efd44941ac90ddc8e8923</sub>

Android test report

Suite Tests Result Skipped
Unit (debug) 43 ✅ pass 0

Coverage: 2.9% of lines

Updated by the android workflow · commit 87e14d060a

<!-- android-test-report --> ## Android test report | Suite | Tests | Result | Skipped | | --- | --: | --- | --: | | Unit (debug) | 43 | ✅ pass | 0 | **Coverage:** 2.9% of lines <sub>Updated by the android workflow · commit 87e14d060aab364a019efd44941ac90ddc8e8923</sub>
nalum force-pushed feat/tokens-warning-role from 1a073fbc2b
All checks were successful
check / commits (pull_request) Successful in 6s
check / go (pull_request) Successful in 2m47s
android / build (pull_request) Successful in 6m33s
check / web (pull_request) Successful in 4m25s
check / report (pull_request) Successful in 4s
android / report (pull_request) Successful in 4s
to 87e14d060a
Some checks failed
android / build (pull_request) Successful in 6m55s
check / commits (pull_request) Successful in 16s
check / go (pull_request) Successful in 2m49s
check / web (pull_request) Successful in 4m4s
android / report (pull_request) Successful in 3s
check / report (pull_request) Successful in 4s
android / build (push) Has been cancelled
android / report (push) Has been cancelled
check / commits (push) Has been cancelled
check / go (push) Has been cancelled
check / report (push) Has been cancelled
check / web (push) Has been cancelled
tag / tag (push) Has been cancelled
2026-08-26 07:03:48 +00:00
Compare
nalum changed target branch from feat/queue-grouped-writes to main 2026-08-26 18:33:34 +00:00
nalum merged commit 87e14d060a into main 2026-08-26 18:33:38 +00:00
nalum deleted branch feat/tokens-warning-role 2026-08-26 18:33:38 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
eagraiclainne/app!207
No description provided.