Skip to content

chore: author import-ready Tokens Studio JSON for the missing beta colour tokens - #5227

Draft
pomfrida wants to merge 1 commit into
mainfrom
chore/tokens-studio-beta-colour-proposal
Draft

chore: author import-ready Tokens Studio JSON for the missing beta colour tokens#5227
pomfrida wants to merge 1 commit into
mainfrom
chore/tokens-studio-beta-colour-proposal

Conversation

@pomfrida

Copy link
Copy Markdown
Collaborator

Part of #5221, follow-up from the Button migration test case (#5208).

What

Import-ready Tokens Studio proposal sets in packages/eds-tokens/token-proposals/5221-beta-colour-gaps/, generated deterministically from the current studio tokens pull by build-proposal.mjs (re-run it after a new pull to rebase the proposal). The three JSON files are complete replacement sets for their counterparts in src/tokens/raw/, so the diff against the raw sets is exactly the proposal. README.md in the folder is the design-review document: change list with rationale, computed-value table, open questions, and import instructions.

Content

  • Alpha step twins {accent,neutral,danger}-alpha.{3,7} in the scheme sets as explicit hex8 values (🎨 Implement Alpha‑Channel approach for disabled states #4741 — the platform only evaluates colour formulas in the CSS export, so modify formulas are not an option). Each twin composites to its opaque step exactly over white (light) / black (dark); deviation over the actual canvas is ≤ ±12/255 and reported per twin. Colour math matches scripts/generate-ts-tokens.mjs.
  • Semantic fill group background.fill.{tone}.{default,hover,pressed,disabled} → steps 9/10/11 + alpha-3 (the values the migrated Button consumes directly today).
  • Neutral/danger equivalents of the accent-only background.surface group, mirrored step for step.
  • Tone text/border: text.{tone} → step 12, border.{tone} → step 8. text.accent repointed from {info.8} (link blue, still available as text-link) to {accent.12}.
  • Name-collision fixes: the semantic layer becomes the single owner of border-focus (→ {info.7}, removing the self-reference), border-disabled and text-disabled (→ {neutral-alpha.7}); the scheme sets drop their duplicates. text-disabled had the same double-value collision as border-disabled and is fixed the same way.

The generated artifacts are added to .prettierignore so they keep the studio-pull JSON style and diff cleanly against src/tokens/raw/.

Verification

build-proposal.mjs resolves all 376 references across the proposal sets, checks that no flattened --eds-* name is declared by both the semantic and a scheme set, and asserts each alpha twin composites back to its opaque step exactly.

Out of scope

…lour tokens

Generated proposal sets (semantic, scheme/light, scheme/dark) closing the
gaps the Button migration surfaced in the beta colour export: alpha step
twins for disabled states, a semantic fill group, neutral/danger surface
equivalents, tone text/border tokens, and the border-focus/border-disabled/
text-disabled name-collision fixes.

Part of #5221
@pomfrida pomfrida self-assigned this Jul 23, 2026
@pomfrida
pomfrida marked this pull request as draft July 23, 2026 12:53
@pomfrida

Copy link
Copy Markdown
Collaborator Author

@claude review

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown

Claude finished @pomfrida's task in 2m 49s —— View job


Review: import-ready Tokens Studio JSON for beta colour gaps

  • Read build-proposal.mjs (generator + verification logic)
  • Read README.md (design-review document)
  • Spot-check the generated JSON sets (semantic + scheme)
  • Check .prettierignore changes
  • Verify the generator's claims by re-running it

I ran the generator and checked its claims against the raw sources. This is a high-quality, self-verifying PR — the approach is sound and the diff is trustworthy.

Verified ✅

  • Idempotent generation. Re-running node build-proposal.mjs produces a zero-line diff against the committed JSON, so the artifacts genuinely match the generator.
  • Verification passes. 376 references verified, no CSS name collisions. — every {ref} resolves against the combined scheme+semantic sets, and the flattened-CSS-name collision check is real (it maps paths to --eds-* names exactly the way resolveToChannels does, segments.join('-')).
  • Alpha-twin table is reproducible. The console table matches README.md row-for-row (values, alpha %, canvas deviation). The composite-exactness assertion in alphaTwin (composite.every((c,i) => c === target[i])) is a genuine guarantee, and it picks the minimal alpha deterministically.
  • Collision/double-value claims are accurate. Confirmed against src/tokens/raw/: semantic border.focus = {border-focus} (the self-reference), semantic border.disabled = {neutral.2} vs scheme {neutral.7}, semantic text.disabled = {neutral.5} vs scheme {neutral.7}. The fix (semantic becomes sole owner, scheme sets drop the duplicates) is correctly implemented.
  • retone string-replace is safe. background.surface.accent references only {accent.*} steps, so JSON.stringify(...).replaceAll('{accent.', '{neutral.') mirrors cleanly with no accidental cross-tone matches ({accent-alpha. is not matched by {accent.).

Observations / minor suggestions (non-blocking)

  1. Duplicated colour math (maintenance risk). oklchToChannels / gamut-mapping is copied verbatim from scripts/generate-ts-tokens.mjs (the header says so). If that source ever changes its conversion, this copy diverges silently — the exactness assertions here are relative to this copy, not the shipped tokens. Low risk since the proposal is regenerated on demand, but worth a note, or importing the shared helper if it's exportable.

  2. Strict oklch() regex. ^oklch\(([\d.]+) ([\d.]+) ([\d.]+)\)$ (line 92) won't match percentage lightness, none hue, or / alpha forms. It fails loudly via fail() rather than producing wrong output, which is the right default — but given the "re-run after each studio tokens pull" workflow, a future export-format tweak would break the rebase. Fine as-is; just flagging the coupling.

  3. icon.disabled is a value change, not just a collision fix. Line 322 repoints icon.disabled ({neutral.5}{neutral-alpha.7}) alongside the true collision fixes. It's not a duplicated CSS name like the other three, so it's a disabled-strength change bundled in. It is covered by open question fake-bot added new tokens #2, so this is intentional — just make sure design reviewers see it as a behaviour change, not a no-op.

  4. .prettierignore glob scope. packages/eds-tokens/token-proposals/**/*.json ignores all JSON under any future proposal folder, not just this one. Presumably intended (all proposals are studio-pull-style), but confirm that's the desired blanket scope. Also note the file has pre-existing duplication (packages/eds-icons/src/data.ts appears twice) and no trailing newline — not introduced here, but the new block lands in a slightly messy file if you want to tidy it in passing.

Design sign-off still needed

The README's open questions are the right ones to gate on — derived alpha percentages becoming canonical (#1), standardising disabled strength on step 7 (#2), and the text.accent{accent.12} repoint being covered by text-link (#3). None are code issues; they're design decisions this PR correctly defers.

Nice work — the generator-as-proof-of-diff pattern makes this genuinely reviewable.
chore/tokens-studio-beta-colour-proposal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant