Skip to content

feat(design-tokens): adopt the new mittwald brand colors - #3459

Draft
Jan-Eimertenbrink wants to merge 47 commits into
nextfrom
feat/brand-color-tokens
Draft

Jan-Eimertenbrink wants to merge 47 commits into
nextfrom
feat/brand-color-tokens

Conversation

@Jan-Eimertenbrink

@Jan-Eimertenbrink Jan-Eimertenbrink commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Brings the new mittwald brand colors into Flow and restructures the color token tiers. Each resolved decision of #3448 lands here as a commit; the draft is the visual reference for the next one.

Part of #3448

Done

  • Tier responsibilities — ADR 0007 (Define the responsibility of each color token tier #3450): Brand → Semantic → Variant → Component. Brand is theme-neutral, Semantic is the only tier that switches light/dark, component tokens never reference Brand.
  • Contrast audit (Build a WCAG contrast audit for color token pairs #3452): pnpm nx audit:contrast tokens reports WCAG 2.2 AA for every content/background pair in light and dark; pairs come from token names. Baseline: light 2 fail + 23 large-only, dark 10 fail + 3 large-only.
  • Today's colors restructured into the tiers without visual change (Restructure today's color tokens into the ADR 0007 tiers without visual change #3462): color-brand.yml, color-semantic.{light,dark}.yml, color-variant.yml. The build emits Semantic per theme, all Brand bypasses are rewired (decorative colors provisionally to decorative-* ramps), build-tokens.js checks references, and the migration entry color-tokens-brand-theme-neutral is in place. Every CSS variable and json-runtime token resolves to the same value per theme as before; visual suite green.
  • Brand palette (Represent the brand palette in global tokens #3453): color-brand.yml takes the Figma Color Primitives 1:1 — mittwald-blue/-navy/-green/-lilac/-orange, mittwald-neutral, system-danger/-warning/-success (19-step hue ramps), 10-step black-alpha/white-alpha, no Info. Old palettes removed; amaranth-red/royal-orange/espelkamp-green stay as legacy until Evaluate the brand's status colors for functional use #3454. Semantic points at the new ramps provisionally (nearest luminance per theme). Audit: light 2 fail + 30 large-only, dark 10 fail + 8 large-only (no new fails). Visual suite: 216 light / 16 dark diffs, baselines deliberately not updated. Migration entry covers the removed palettes.
  • Neutral ramp and border role (Propose a revised neutral ramp to the brand team #3539), provisional until the brand team approves (Re-sync the neutral ramp with the brand team's approved revision #3542): mittwald-neutral as 19 steps (the 12 approved values on new numbers plus 7 in-between steps), calmer neutral hover/pressed, secondary text one half step stronger, and a Semantic border role with lighter control borders (light #777C84, dark #888D96). Gate 249 → 171 allowlisted. Reverted if the brand team rejects it.

Open

Ships as a Minor: token names and values are outside the semver contract (ADR 0005).

🤖 Generated with Claude Code

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>
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Preview environments are ready:

Type URL
docs pr-3459.docs.review.flow-components.de
storybook pr-3459.storybook.review.flow-components.de

Images:

  • docs: ghcr.io/mittwald/flow/docs:pr-3459
  • storybook: ghcr.io/mittwald/flow/storybook:pr-3459

`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>
@Jan-Eimertenbrink Jan-Eimertenbrink added the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Oct 12, 2026
@github-actions github-actions Bot removed the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Oct 12, 2026
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

❌ Visual Regression Tests Failed

At 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 update-screenshots label to the PR.

Run details

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>
@Jan-Eimertenbrink Jan-Eimertenbrink added the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Oct 13, 2026
@Jan-Eimertenbrink Jan-Eimertenbrink added run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch and removed run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch labels Oct 13, 2026
@github-actions github-actions Bot removed the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Oct 13, 2026
…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>
Jan-Eimertenbrink and others added 4 commits October 13, 2026 10:04
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>
…ration

amaranth-red, royal-orange and espelkamp-green left Brand (#3454). The
entry lists them with the other removed palettes and points them at
--danger--, --warning-- and --success--color--N.

Part of #3454

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jan-Eimertenbrink Jan-Eimertenbrink added the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Oct 13, 2026
…3454

# Conflicts:
#	packages/codemods/src/migrations.generated.ts
#	packages/codemods/src/tests/guide.test.ts
#	packages/components/MIGRATION.md
Jan-Eimertenbrink and others added 7 commits October 27, 2026 13:56
UX decided in #3456 that AccentBox green takes the brand's green instead of
keeping the success mint: the AccentBox is decorative. green is deprecated
toward sage, now renders exactly like it, and the codemod
color-props-brand-palette renames it. The accent-box green token and class
are gone; their two contrast allowlist entries with them (237 -> 235).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dark primary quiet.100–300 moves from mittwald-blue 1800/1700/1600 to
1600/1500/1400. On 1800 a primary soft Button vanished into the card
(1.01:1 against elevation.100); 1600 lifts it to 1.13. UX compared
1700, 1600 and 1500 side by side and picked 1600: 1500 (1.22, level
with secondary soft) read too loud.

Plain and outline hover/pressed, the DatePicker range and TimeField
pressed share these tokens and lighten with it. Text stays AA: soft text
(blue 300) 7.41 at rest, 6.24 pressed; the link (blue 400) on plain
pressed 5.60. No allowlist change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Light decorative-navy quiet.100–300 moves from mittwald-navy 400/500/600
to 300/400/500. On 400, navy outweighed the other decorative surfaces
(1.74:1 against the card; lilac 1.51, salmon 1.56, sage 1.62), which
UX noticed in Avatar, where navy is the default, and in the sender
Message. 300 sits at 1.56. UX compared 300 and 200 side by side and
picked 300: 200 read washed out. This departs from the brand's
Background/Brand-100 (navy 400, #3550). Dark stays on 1700, already the
quietest decorative surface after blue.

Badge navy and AccentBox navy share the token and lighten with it.
Contrast improves: initials 8.07 → 8.99, link on the sender Message
4.80 → 5.34. Danger text and the invalid field border now pass on the
navy tints; their 8 allowlist entries go, and the remaining light navy
and sender-Message floors are raised to the new ratios.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Content containers looked boxy next to LayoutCard and Modal: they
shared 8px with the controls inside them, while surfaces had 24px. The
scale jumped from m (8) straight to l (24).

The scale keeps its names and gains a step: l is 16px now, the new xl
takes 24px. Radii follow the element's role, and a nested element sits
at least one step below its container (documented in border.yml):

- xl: LayoutCard, Modal (and Badge, ProgressBar, which keep their 24px)
- l: Table, List items and tiles, AccentBox, Alert, Message,
  Notification, FileCard, Accordion, CodeBlock, Image, FileDropZone,
  ImageCropper
- m, s, round: unchanged

UX decided the 16px and to keep the s/m/l names. Direct users of
--corner-radius--l get 16px as well: in the docs app the component
card, the file preview frame and the wireframe bars (which stay pills).

Alert and Notification draw their start edge as a masked layer in their
own shape. As a wide border-inline-start (Alert) or a 3px element with
the corner radius (Notification), the edge bent into the larger radius.
Now its outer edge follows the corner and its inner edge stays
straight; content keeps its position.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Popover is a container like the content containers: ContextMenu,
ContextualHelp and the DatePicker calendar group controls inside its
padding (MenuItem 8px, 8px padding). By the radius rule it sits one step
above them, at l (16px), instead of sharing m (8px) with its items. The
ChartTooltip shares the token. Tooltip stays at m.

A separate commit, so UX can review and revert it on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
corner-radius.l drops from 16px to 12px (UX). 12px sits between the
size-px steps s (8) and m (16), so the token takes the literal value.
Every l container follows: Table, List, AccentBox, Alert, Message,
Notification, FileCard, Accordion, CodeBlock, Popover, …

The start stripe of Alert (was 8px) and Notification (was 4px) now
references the element's own corner radius. A stripe narrower than the
radius ended inside the corner curve; as wide as the radius it ends
where the curve ends, and it follows any later radius change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@@ -0,0 +1,78 @@
---
since: 1.5.0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both new catalogue entries say since: 1.5.0, but they ship with 1.6.0. upgrade selects every entry with since <= target, so a consumer on 1.5.x running upgrade patch (target 1.5.53) gets this codemod and ends up with color="danger"/"sage", which 1.5 doesn't know. Same in color-tokens-brand-theme-neutral/entry.md, then pnpm nx build codemods.

Suggested change
since: 1.5.0
since: 1.6.0


/* The start edge is masked out of a layer in the alert's shape: as a
border-inline-start it bent into the corner radius. */
&::before {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the border gone, the surface and the start stripe are both background-color, which forced-colors mode (Windows high contrast) replaces with Canvas. The Alert then has no visible boundary at all; before, the 1px border survived as CanvasText. A @media (forced-colors: active) { border: 1px solid CanvasText; } on .alert would keep it apart from the surrounding content.

red: "danger",
},
Avatar: decorative,
Icon: decorative,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated icons (IconCheck, …) take ComponentProps<typeof Icon>, so they accept the deprecated color values too, but only the name Icon is matched here. <IconCheck color="violet" /> stays as it is and keeps warning. Could imports matching /^Icon[A-Z]/ (and Flow.IconX) be treated like Icon?

: undefined;

const backgroundColor =
useDeprecatedColor(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the legacy color="gradient" / color="green" path, this warns "Use 'gradient-navy' instead" without saying it belongs on backgroundColor. Following it literally (color="gradient-navy") drops the gradient. Maybe a dedicated message for that path (Use backgroundColor="gradient-navy")? The codemod also only rewrites backgroundColor, so these stay untouched.

@Lisa18289 Lisa18289 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apps/docs/src/content/foundations/design/colors/index.mdx:22

8 of the 12 DesignTokenTables on the Colors page point at groups this PR removes (color.gray, color.hosting-blue, color.espelkamp-green, …). They render empty without a build or test failure, so nothing stops the page from going live like that once next is released. #3465 is still on the list here, so this only matters if the PR is merged before that's done.

args: { color: "blue" },
};

export const Colors: Story = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

die story brauchts nicht die farben sieht man alle in der ersten story (umschaltbar über controls)


export const Default: Story = {};

export const Colors: Story = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

die story brauchts nicht die farben sieht man alle in der ersten story (umschaltbar über controls)

# Conflicts:
#	packages/design-tokens/src/dataVisualisation/area.yml
@Lisa18289 Lisa18289 added the update-screenshots Label a PR to update the screenshots used for visual regression testing label Nov 2, 2026
@github-actions github-actions Bot removed the update-screenshots Label a PR to update the screenshots used for visual regression testing label Nov 2, 2026
Co-authored-by: Lisa18289 <84317589+Lisa18289@users.noreply.github.com>
value: "{corner-radius.l}"
# No border: the soft surface carries the Alert, the start edge keeps it
# apart from the AccentBox (#3564).
border-width:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

die border width kann weg wenn sie nicht mehr genutzt wird

corner-radius:
value: "{corner-radius.m}"
value: "{corner-radius.l}"
# As wide as the corner radius: the stripe ends where the corner curve

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kommentar kann weg

1900:
value: "#1d202a"

mittwald-green:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wollen wir hier auch auf sage wechseln?

1900:
value: "#25222d"

mittwald-orange:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wollen wir hier auch auf salmon wechseln

value: "{size-px.xs}"
m:
value: "{size-px.s}"
# 12px sits between the size-px steps s (8) and m (16), set by UX.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kommentar kann weg

@@ -0,0 +1,437 @@
# Semantic tier (ADR 0007), dark theme: colors with a meaning. The only

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hier und auch an anseren stellen sind sehr viele kommentare, evtl kann man da noch etwas kürzen, und nur drin lassen was in zukunft zum arbeiten mit den jeweiligen token etc nötig ist.

@@ -0,0 +1,642 @@
# Variant tier (ADR 0007): pairs of Semantic colors per variant. References

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADR 0007 würd ich nicht erwähnen wenn er nur während des entwickeln der neuen Tokens wichtig war

import { fileHeader, formattedVariables } from "style-dictionary/utils";
import { propertyFormatNames } from "style-dictionary/enums";

/*

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in der datei werden auch wieder viele ADRs, MRs und Issues erwähnt, würde ich auch weglassen

@Lisa18289

Copy link
Copy Markdown
Member

packages/remote-react-components/src/tests/visual/screenshots/AccentBox.browser.test.tsx/AccentBox-colors-firefox-linux.png -> screenshots sind zu hoch geworden, die Accentboxen werden nicht mehr ganz angezeigt, ectl auf zweispaltig (ColumnLayout) umstellen

@Lisa18289

Copy link
Copy Markdown
Member

die separator, zb hier bei den accordions (packages/remote-react-components/src/tests/visual/screenshots/Accordion.browser.test.tsx/AccordionGroup-firefox-linux.png) sind im darkmode schon sehr schwer zu erkennen, evtl müssen die doch etwas kräftiger/heller sein?

Jan-Eimertenbrink and others added 4 commits November 2, 2026 16:27
#3435 left four component color tokens as literals or on a role that
misses dark. Each now references Semantic (ADR 0007), decided with UX:

- area.dot-background-color: {elevation.color.100}. Matches the area
  border it sits on; dark was pure black, now the card surface.
- password-creation-field.complexity-shimmer-color:
  {light-static.color.strong.300}. White 70% instead of 80%: Semantic
  has no 80% step, and 70/80/90% look the same on the bar.
- skeleton.background-color: {neutral.color.quiet.100}. Light stays
  close to the old tint; dark is a quiet dark surface instead of a
  bright blue-gray.
- skeleton.shimmer-color: {light-static.color.quiet.300}. Stays white
  in dark; the theme-aware `light` group turns black there and the
  shimmer vanishes on the dark skeleton.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
skeleton.shimmer-color moves from {light-static.color.quiet.300} to
{light.color.quiet.300}: white 30% in light, black 30% in dark. UX
prefers the barely visible dark shimmer over a white sweep on the dark
skeleton. a312c0e had picked the static value without that decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
skeleton.shimmer-color moves from {light.color.quiet.300} to
{elevation.color.100}: white in light, #1d1e1f in dark. The same alpha
reads three times weaker in light: the light bar sits close to white,
so a white veil barely lifts it (shimmer peak to bar 1.07 light, 1.20
dark). Opaque elevation.color.100 is even in both themes (1.23 / 1.24).
No single alpha step balances them, since a component token cannot pick
a step per theme. Decided with UX against three alternatives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…roved

The brand team's approval counts as given (#3542, 2026-11-02): the
neutral ramp, the AccentBox gradients (#3456) and sage/salmon (#3508)
stand as proposed. No values change.

- color-brand.yml: drop "approval pending" and "Provisional until the
  brand team reviews them".
- ADR 0007: the brand gradients are in Brand; `gradient` is replaced,
  only `background-gradient` stays a Semantic literal.
- Contrast allowlist: "#3456 decides the AccentBox colors" → "set".

Closes #3542

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

2 participants