Repository navigation
feat(design-tokens): adopt the new mittwald brand colors - #3459
Conversation
Brand (Global) holds the theme-neutral brand palette, Semantic (Alias 1) is the only tier that switches light/dark, Variant (Alias 2) pairs Semantic colors, and component tokens never reference Brand. A reference check in build-tokens.js enforces the rules. Closes #3450 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🚀 Preview DeploymentPreview environments are ready:
Images:
|
`pnpm nx audit:contrast tokens` builds the tokens and reports the WCAG 2.2 AA ratio of every content/background pair in light and dark: text 4.5:1, icons and handles 3:1, disabled states exempt. Pairs come from token names, not file paths, so the tier restructure (#3462) keeps them: a `…content-color`, `…icon-color` or `color` token pairs with the sibling named `…background-color`, per state, falling back to `default`. Translucent backgrounds are composited on the theme surface (`neutral.color.100`); `light` pairs on its inverse, `*-static` pairs on black or white. Report only; `--strict` exits 1 on a failure for a later CI gate. Closes #3452 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Today's colors move into the tiers of ADR 0007 without a visual change:
- `color-brand.yml`: the palette, theme-neutral (today's light values).
`static-black-alpha`/`static-white-alpha` are gone.
- `color-semantic.{light,dark}.yml`: the only light/dark switch. Ramps
reference the mirrored Brand step in dark; gray keeps today's values
(100–1000 take gray.1000–100, 1100/1200 stay white). `transparent`,
`categorical`, `code-syntax`, `gradient` and `background-gradient` move
here as `<group>.color` literals. Decorative colors get provisional
ramps `decorative-{blue,navy,violet,teal,lilac,red,green,orange}.color`
until #3455 defines the final roles.
- `color-variant.yml`: the variant pairs, referencing Semantic only.
The build emits Semantic per theme instead of Brand. The 81 component
references to Brand, Variant's `transparent` and the Brand CSS variables
in component and docs code are rewired. `build-tokens.js` now fails on a
reference ADR 0007 forbids, a literal outside the Semantic literal groups
and a Semantic key defined for one theme only.
Every CSS variable resolves to the same value as before in light, dark
and both system variants, and so does every json-runtime token. Only the
108 Brand variables differ in dark: they keep their light value. A
manual migration entry covers consumers reading Brand variables.
Part of #3462
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ Visual Regression Tests FailedAt least one shard did not pass. If snapshots differ from the committed baselines, download the visual-diffs-* artifacts from this run to inspect the actual/diff images (a shard that failed before comparison, e.g. during install or browser setup, leaves none). If the differences are intentional, update the baselines by adding the |
Brand takes the Figma "mittwald. Global Tokens" Color Primitives 1:1 (#3453): 19-step ramps mittwald-blue/-navy/-green/-lilac/-orange and system-danger/-warning/-success, a 12-step mittwald-neutral and 10-step black-alpha/white-alpha. The brand's Info ramp duplicates mittwald-navy and is left out. gray, hosting-blue, the old mittwald-navy, soft-contrast-violet, bright-lilac, super-teal and the 8-step alpha ramps are removed. Semantic references the Brand step closest in luminance to each value before, per theme, until #3455 defines the roles: info moves to mittwald-navy, decorative-violet to mittwald-lilac, decorative-teal to mittwald-green. The legacy status ramps stay until #3454. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…an-4c5709 # Conflicts: # eslint.config.js
…igration The entry said every other --color--<ramp>--N still exists and Flow renders as before. Since #3453 gray, hosting-blue, soft-contrast-violet, bright-lilac and super-teal are gone, mittwald-navy and the alpha ramps carry new values, and Flow picks up the brand palette. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ADR 0007: code reads Semantic or Variant colors, never Brand. Brand is
theme-neutral, so a Brand variable stays light in dark.
`flow/no-brand-color-variable` rejects `--color--<brand-group>--…` in
stylesheets (stylelint) and TS/TSX strings (ESLint) in packages/components
and apps/docs. The groups are read from design-tokens/src/color-brand.yml,
so a new group is covered without touching the rules. A name completed at
runtime (`--color--#{$hue}`, `` `--color--${hue}` ``, `"--color--" + hue`)
is rejected when a Brand group can complete it: only Brand defines tokens
under `color`. Declarations that redefine a Brand variable and at-rule
params (mixin arguments) are checked too.
Exempt: the docs pages that display the palette (foundations/design/colors,
design-tokens), and the llms export test of the palette table via an inline
disable. The codebase was already clean after the restructure (#3462).
Closes #3463
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntrast in CI The contrast audit now also rates content colors without a background sibling against the backgrounds they render on, in light and dark: `text`, `heading`, `link`, `icon`, `alert-text`, Alert and Notification headings, label, breadcrumb, IllustratedMessage, plain Kbd, loading spinner, placeholder, and — at 3:1 (WCAG 1.4.11) — focus ring, form-control borders, checkbox/radio and slider track. Surfaces come from the components' SCSS: page (neutral 100 / 200), LayoutCard, Modal and its footer, Popover, Table and striped rows, AccentBox colors, Message bubbles, ListItem, FileCard, Notification. Hover/pressed states of clickable containers carry their own content only, not form fields or the focus ring. Borders that only group content are not rated. `pnpm nx test:contrast tokens` runs the audit with `--strict` and is part of `pnpm test` and `affected:test`. It fails on a failure missing from `dev/contrast-audit-allowlist.js`, on an allowlisted pair below its recorded ratio, and on an allowlisted pair that passes now. The allowlist holds today's 162 known failures in five groups, each with its cause and the ticket that fixes it (#3454, #3455). Closes #3480 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Semantic danger, warning, success and info now reference the brand's system-danger/-warning/-success ramps (info: mittwald-navy) with steps chosen per role, not by nearest luminance: | Semantic | Role | light (success) | dark (success) | | --- | --- | --- | --- | | 100–300 | soft, plain hover/pressed | 100–300 | 1800–1600 | | 800 | solid, plain, border | 1300 (1600) | 700 (1000) | | 900 | text, solid hover | 1500 (1700) | 500 (600) | | 1000 | solid pressed | 1600 (1800) | 400 (500) | 400–700 and 1100 are unused outside Semantic and fill the ramp in order. The brand bases (1000) carry no white text in light (danger 3.67, warning 2.75, success 1.63), so light solids take darker steps; dark success solid is the base itself. Danger and warning share their steps; they stay apart at ΔE 9.2 (light solid) and 4.9 under tritanopia (dark solid). decorative-red/-orange/-green mirror danger/warning/success. The legacy amaranth-red, royal-orange and espelkamp-green ramps are removed from Brand. Contrast gate: 65 allowlisted failures pass now, among them every warning failure. New allowlist groups record the accepted ones: plain status buttons on their own pressed tint (4.24–4.26, warning 3.41/3.72), content on the darker brand tints in light (#3479), and the darker dark status text on AccentBox violet/green and gray pressed surfaces (#3455, #3456). Part of #3454 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…3454 # Conflicts: # packages/codemods/src/migrations.generated.ts # packages/codemods/src/tests/guide.test.ts # packages/components/MIGRATION.md
Co-authored-by: Lisa18289 <84317589+Lisa18289@users.noreply.github.com>
The Brand palette is maintained in the brand library, so the Colors page no longer repeats it; the Aufbau section still explains the Brand tier. The page's Best Practices list goes too. The neutral roles state what each step is for instead of listing the components that use it. Navy and the Light and Dark colors lose their component examples for the same reason. The tier table on the Design Tokens page drops its Light und Dark column; the sections below it say the same. AccentBox, Badge, Icon and Color called blue/navy/lilac/sage/salmon "Brand Colors", which now names the palette tier. They are Decorative Colors and link to that section. The Color status example used the misspelled value "unavialable". The Avatar color example now shows all five decorative colors and one icon instead of two. Refs #3465 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dark `border.color.200` moves from `mittwald-neutral.1500` to 1400 (#404448). At 1500 the separators were hard to see on dark surfaces (review on #3459): 1.44 on cards, modals and popovers, 1.58 on the page. Now 1.70 and 1.86. Light stays at 500 (1.45 on white). The same ratio reads weaker on a dark background. Affects every `border.200` consumer in dark: Separator, Section, AccordionGroup, Calendar presets, ListItem, Table (also in Markdown), FileCard and the CartesianChart grid. Card and overlay borders (`border.100`, 1600) stay. The contrast gate does not rate these borders; the allowlist is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0007 is already beta packages, on main and next. Links in the lint rules, build-tokens.js, the token YAML headers, both AGENTS.md and the migration entry follow; MIGRATION.md is regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`upgrade` selects every entry with `since <= target`, so `since: 1.5.0` handed the codemod to a 1.5.x consumer, whose Badge does not know `danger` or `sage`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comments keep what holds: the tier rules, the role legend, which step a role takes and why, and for the contrast allowlist which pair reaches which ratio and that UX accepts it. Issue references, approvals, ΔE values and Figma file names go; git blame leads to them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kens Forced colors replace the surface and the start stripe, both backgrounds, with Canvas, so the borderless Alert lost its edge in Windows high contrast. A 1px CanvasText border brings it back there. `--alert--border-width` was 0 and `--alert--border-style` had nothing to style, so both tokens and the border declarations go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The color control of the other stories shows every color already. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`IconCheck` & co. take `Icon`'s props, deprecated colors included, but `color-props-brand-palette` matched only the name `Icon`. Imports matching `/^Icon[A-Z]/` from a Flow package, and `Flow.IconX`, now get `Icon`'s renames. AccentBox's legacy `color="gradient"`/`"green"` needs no case: `accent-box-color-to-background-color` moves it to `backgroundColor` first in `upgrade`, where this transform renames it. The entry's `apply` names the step for a manual migration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`color="gradient"`/`"green"` warned "Use 'gradient-navy' instead". Followed literally, `color="gradient-navy"` drops the gradient. The legacy path now says `Use backgroundColor="gradient-navy" instead`; `useDeprecatedColor` takes the prop the replacement belongs on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… roles Ten AccentBoxes in one column outgrew the screenshot; three columns fit all of them. Two columns still cut off the last row. The AlphaColor backdrops were the old hex #3A434E and #E5EFF8, beside the theme's own `neutral` AccentBox. They now take two Semantic roles, so each theme shows two backdrops: the `neutral` AccentBox (elevation.300) and the strong neutral surface (neutral.strong.100). Baselines follow in #3507. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: - AccentBox.tsx: kept next's FlowComponentProps<HTMLElement> and ref forwarding (#3593) together with the PR's backgroundColor JSDoc (@deprecatedValues violet, teal, green, gradient). - SkeletonModeFormFields SkeletonMode-input-fields-{firefox,webkit}-linux.png: took the PR side. All baselines get regenerated at the end anyway (#3507). No semantic conflicts: next brought no color token references; #3435 was already part of this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AccentBox visual test too tall Changed in 055e21f. Two columns still cut off the last row (five rows of boxes are taller than the 720px screenshot), so it uses three: four rows, all ten boxes visible. The baseline follows in #3507. Changed in 055e21f. The AlphaColor backdrops were still the old hex Resolved by cf567a5 and a030ca7 (#3465): every |
Co-authored-by: Lisa18289 <84317589+Lisa18289@users.noreply.github.com>
These 10 firefox-linux baselines still render the dark primary as #85afff; the branch renders #9f9eef. The difference stays under the comparator threshold, so update-screenshots never rewrote them. Without a reference, the next update-screenshots run writes them from the current code. Part of #3507 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both sides changed the linux baselines of DateRangePicker-states and SkeletonMode-input-fields: next for the DateRangePicker fix (#3625), the branch for the brand colors. Neither image fits the merged code, so the merge drops them and update-screenshots writes them fresh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Jan-Eimertenbrink <166510726+Jan-Eimertenbrink@users.noreply.github.com>
Brings the new mittwald brand colors into Flow and restructures the color tokens into three tiers.
Closes #3448
Closes #3507
What changes
build-tokens.jsfails on a forbidden reference.color-brand.yml):mittwald-blue/-navy/-green/-lilac/-orange, a 19-stepmittwald-neutral,system-info/-danger/-warning/-success,black-alpha/white-alpha, and a light and a dark value per brand gradient. The old palettes are gone.color-semantic.{light,dark}.yml): named roles instead of mirrored ramps. Colored groups havequiet/strong100–300; the neutral ramp haselevation,contentandborder; each brand color has adecorative-<hue>group.color-variant.yml) and all component tokens reference Semantic.pnpm nx audit:contrast tokensreports WCAG 2.2 AA in both themes.pnpm nx test:contrast tokensgates CI;dev/contrast-audit-allowlist.jslists each accepted failure with its ratio.flow/no-brand-color-variable(stylelint and ESLint) rejects Brand variables incomponentsandapps/docs.Badge,Avatar,Icon,ColorandAccentBoxoffer one decorative color per brand color:blue,navy,lilac,sage,salmon.Badgenames its status huessuccess,warning,danger. The old values are deprecated, keep working and warn.AccentBox: brand gradientsgradient-navy/-sage/-lilac/-salmon; content defaults todarkon colored backgrounds.Alert: soft surface and a start stripe instead of a border; a 1pxCanvasTextborder in forced-colors mode.Badgehas no border.List,FileCardandTabletake the lighter separator border.xl24px for surfaces (LayoutCard, Modal),l12px for content containers.color-props-brand-palette(codemod, generated icons included) andcolor-tokens-brand-theme-neutral(manual), bothsince: 1.6.0.Ships as a Minor: token names and values are outside the semver contract (ADR 0005), and deprecated prop values keep working.
🤖 Generated with Claude Code