feat(tokens): add saturated surface tokens for danger/success/warning/info#7439
Closed
talissoncosta wants to merge 1 commit intomainfrom
Closed
feat(tokens): add saturated surface tokens for danger/success/warning/info#7439talissoncosta wants to merge 1 commit intomainfrom
talissoncosta wants to merge 1 commit intomainfrom
Conversation
…/info
The action intent has a complete surface family (subtle, muted, base,
hover, active) — every other intent only had the subtle 0.08-alpha
tint. That asymmetry forced the design system to fill the gap with
hardcoded hex colours and primitive references in _variables.scss
($btn-danger-hover, $btn-success-active, etc.) — silently bypassing
the token system for every saturated intent button.
Adds 12 new surface tokens (4 intents × 3 states) using the `Strong`
qualifier already in use by colorBorderStrong:
--color-surface-{intent}-strong # saturated bg
--color-surface-{intent}-strong-hover # hover state
--color-surface-{intent}-strong-active # active state
Light theme uses the {intent}-500/600/700 primitive scale; dark
theme shifts one step lighter (-400/500/600) for contrast — same
pattern action follows.
Pure additive change. Auto-generated tokens.ts, _tokens.scss,
_token-utilities.scss, and TokenReference.generated.stories.tsx
follow from `npm run generate:tokens`.
Action intent stays asymmetric (no Strong qualifier) — its base is
already the saturated brand surface, no rename needed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced May 6, 2026
Contributor
Author
|
Closing in favour of a documented design plan for Button + Link before further code changes. The implementation here was outpacing the architectural decisions — pausing the code, will reopen replacements once the plan is agreed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thanks for submitting a PR! Please check the boxes below:
Changes
TL;DR. Adds 12 saturated surface tokens (4 intents × 3 states) so danger/success/warning/info buttons can use semantic tokens instead of hardcoded hex. Pure additive — no consumers wired up yet.
Why
The token system had asymmetric intent coverage:
That forced `_variables.scss` to fill the gap with hardcoded hex (`$btn-danger-hover: #cd384d;`) and primitive references (`$btn-success-hover: $success;`), silently bypassing the token system for every saturated intent button.
What's new
12 new tokens using the `Strong` qualifier already in use by `colorBorderStrong`:
```
--color-surface-{intent}-strong # saturated bg
--color-surface-{intent}-strong-hover # hover state
--color-surface-{intent}-strong-active # active state
```
For each of `danger`, `success`, `warning`, `info`. Light theme uses the `{intent}-500/600/700` primitive scale; dark theme shifts one step lighter (`-400/500/600`) for contrast — same pattern `action` already follows.
Why `Strong` instead of other naming
Why `action` stays without a `Strong` qualifier
The `action` intent's saturated colour is its default `colorSurfaceAction` (no qualifier). Adding a `Strong` qualifier there would be a breaking rename for zero semantic gain. The asymmetry is honest — `action` is the brand's primary surface and the default; other intents are secondary and need explicit qualification.
How did you test this code?