UDG: code styling tokens (syntax highlighting, diff, mono) #217
Labels
No labels
build-dist
priority
P1
priority
P2
priority
P3
priority
P4
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Toilville/toilville-design#217
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Split out of #89 (VS Code and Xcode theme templates), which is closed as deferred.
ville's 2026-09-29 assessment found no consumer for branded editor themes. The greater need is code styling inside UDG: how code, diffs and terminal output look in Rituals, the docs and the dashboards.
Scope
fontMonoresolution.codeanddiffblock renderers (packages/udg/lib/src/blocks/block_renderers/) and the macOS equivalents.Not in scope
Exporting VS Code or Xcode theme files. If a consumer appears later, those can be generated from these tokens.
Acceptance
codeanddiffrenderers read them, with no hardcoded colours.Approval needed: code tokens for #217, one new colour
Add
color.syntax.*(comment, keyword, string, number, function, type, punctuation) andcolor.diff.added/color.diff.removedto the baseline and Rituals palettes. Thecodeanddiffrenderers will read these tokens. The diff renderer now takes its colours fromcolor.safety.*, which is the governance palette.One new colour:
#4E6552, the Rituals lightsyntax.string. Every other value is an existing UDG value, copied into the role token. A drift test ties each copy to its source.Why
#4E6552is needed. In the Rituals light themes, plum (pilgrimage) and slate (federation) look alike under protanopia (ΔE00 2.3), whichever roles they take. Sage separates from both. The existing light sage (accent.workshop) is 4.49:1 on the code surface, 0.01 short of AA.#4E6552is the same family, slightly darker, at 4.7:1. Dark andvanillanightuse the existing sage#99B78F.Contrast. Every syntax role is at least 4.5:1 on the code surface (
bg.surface-variant) in every theme, with the lowest at 4.50:1. Thevanillanightroles reuse the existing dark values, because its own accent values are 3.5:1.Diff uses Sanctum blue for added and
accent.errorfor removed, not green and red. Green and red tints collapse under deuteranopia (ΔE00 1.2 to 1.7). Blue and red stay apart (5.6 to 8.2, except Rituals light at 3.5, see below). In Rituals,accent.successis rose, so it does not read as green anyway. This is a value copy only:accent.sanctumkeeps its mode meaning.Remaining weak spots (analysis thresholds from the #173 check, not an accessibility standard):
Colour is never the only cue. Diff lines carry a
+or-mark and their content. Syntax colours sit on top of the code text itself.Condition. Baseline
numberusesaccent.warning. It passes AA only with the revised light value in #230.Scope of the PR: DTCG tokens, WCAG pairs, drift test and spec notes in this repo. The Dart and macOS renderer changes are a separate PR in
toilville_rituals.Approved (Peter, 2026-10-27). Go ahead with the PR.
Approving the whole set:
color.syntax.*(comment, keyword, string, number, function, type, punctuation) andcolor.diff.added/color.diff.removedin the baseline and Rituals palettes, plus the one new colour.The new colour is justified and I'm approving it as the exception it is.
#4E6552for Rituals lightsyntax.string— the existing light sage at 4.49:1 is 0.01 short of AA, and shipping a role token that misses the floor by a rounding error is worse than adding one value. The protanopia case for sage over plum/slate (ΔE00 2.3 betweenpilgrimageandfederation) is the right reason to pick the family. Dark andvanillanightreusing the existing#99B78Fkeeps it to one.Your condition is met — I checked rather than assuming. Baseline
numberdepends on the revisedaccent.warning, and #230 is merged:Brand/UDG/dtcg/color.jsonnow carriesaccent.warninglight#B43A01,accent.error#AA0110,accent.critical#84014C. None of the three superseded values (#CD4D0B,#DC2626,#960157) survive anywhere in the file. Sonumberpasses AA on the code surface as of now, not conditionally.Blue-and-red for diff instead of green-and-red: yes. Green/red collapsing at ΔE00 1.2–1.7 under deuteranopia is disqualifying for the one UI element people scan fastest, and in Rituals
accent.successis rose, so green was never available anyway. Taking the value fromaccent.sanctumas a copy while the mode meaning stays put is the right mechanism. Moving diff offcolor.safety.*is overdue on its own merits — the governance palette should not be doing double duty as a syntax palette, and a reader has no way to tell which meaning a colour is carrying.The drift test is the part that makes this safe, so treat it as load-bearing, not as test scaffolding. Nearly every value here is a copy, and copies decay silently; the test tying each role token to its source is what keeps "reuses the existing value" true a year from now.
The remaining weak spots are accepted as noted. Rituals light diff at ΔE00 3.5 under protanopia, baseline comment/type at 3.9 under deuteranopia, string/number 3.9–4.0 under tritanopia. These are below the #173 analysis thresholds, not below an accessibility floor — every role still clears 4.5:1 on
bg.surface-variant, and colour is never the only cue, since diff lines carry+/-and syntax colour sits on text that is already legible. Worth a line in the spec notes so the next person reads them as known and accepted rather than as an oversight.Scope as you proposed: DTCG tokens, WCAG pairs, drift test and spec notes here; the Dart and macOS renderer changes as a separate PR in
toilville_rituals. Acceptance stays as the issue body sets it — tokens exist with contrast-pair tests in both themes, and thecodeanddiffrenderers read them with no hardcoded colours.