@helloimjolopez-pathway/pathway-tokens 10.0.0 → 10.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,12 +47,17 @@ import ReactDOM from "react-dom";
47
47
  * Token names verified against the Figma Variables panel on 2026-09-02.
48
48
  */
49
49
  const c = (name) => `var(--semantic-color-${name})`;
50
- const u = (name, fallback) => `var(--semantic-layout-units-${name}, ${fallback}px)`;
50
+ // Elevation is its own collection and already carries the whole shadow string,
51
+ // theme-resolved: light casts rgba(24,27,43,0.08), midnight casts
52
+ // rgba(0,1,19,0.70). A hand-written rgba(0,0,0,0.03) is invisible on a dark
53
+ // canvas, which is exactly how dark mode ended up looking flat.
54
+ const c2 = (name) => `var(${name})`;
55
+ const u = (name) => `var(--semantic-layout-units-${name})`;
51
56
  // Component metrics live in the CONTEXTUAL collection, not the semantic one, so
52
57
  // they need their own prefix. SideNav's two widths moved there on 2026-09-16:
53
58
  // they were numeric literals with a "no token in Figma" comment, which was true
54
59
  // until the tokens were created.
55
- const x = (name, fallback) => `var(--contextual-layout-units-${name}, ${fallback}px)`;
60
+ const x = (name) => `var(--contextual-layout-units-${name})`;
56
61
 
57
62
  // Negate a length that may be either a number or a var() reference. Used for the
58
63
  // scroll-region edge bleed, where `-value` on a string would give NaN.
@@ -94,7 +99,7 @@ export const T = {
94
99
  // The active-item stripe takes the loud brand blue straight from the Action
95
100
  // tier rather than owning a token of its own.
96
101
  indicator: c("fill-action-primary-strong-pressed"),
97
- radius: u("cornerradius-base", 8),
102
+ radius: u("cornerradius-base"),
98
103
  };
99
104
 
100
105
  /*
@@ -111,27 +116,27 @@ export const L = {
111
116
  // collapsed rail 12, vertical 8, item gap 6. These were on the generic
112
117
  // semantic scale until 2026-09-17, which meant a change to Padding/Base
113
118
  // would silently move the nav.
114
- navPadH: x("sidenav-padding-horizontal-expanded", 16),
115
- navColPadH: x("sidenav-padding-horizontal-collapsed", 12),
116
- navPadTop: x("sidenav-padding-vertical", 8),
119
+ navPadH: x("sidenav-padding-horizontal-expanded"),
120
+ navColPadH: x("sidenav-padding-horizontal-collapsed"),
121
+ navPadTop: x("sidenav-padding-vertical"),
117
122
  // Read from SideNav.Container in Figma on 2026-09-16: every expanded variant
118
123
  // is 250 wide (Base, Stroked, Mobile.Base, Mobile.Stroked) and every
119
124
  // collapsed one is 72. Was 240, which no longer matched the component.
120
- navW: x("sidenav-width-expanded", 250),
121
- navWcol: x("sidenav-width-collapsed", 72),
122
- menuGap: x("sidenav-gap-vertical", 6),
123
- menuPadT: u("padding-tight", 8),
124
- menuPadB: u("padding-xxwide", 56),
125
- itemH: u("accessibility-touch-target-aa-height", 44),
125
+ navW: x("sidenav-width-expanded"),
126
+ navWcol: x("sidenav-width-collapsed"),
127
+ menuGap: x("sidenav-gap-vertical"),
128
+ menuPadT: u("padding-tight"),
129
+ menuPadB: u("padding-xxwide"),
130
+ itemH: u("accessibility-touch-target-aa-height"),
126
131
  iconWrap: 24, // no token in Figma — leading icon wrapper
127
132
  iconInner: 16, // Material Symbols Rounded frame size, per design-system-spec §7.2
128
- rowPadH: u("padding-tight", 8),
129
- textPad: u("padding-xtight", 6),
133
+ rowPadH: u("padding-tight"),
134
+ textPad: u("padding-xtight"),
130
135
  childIndent: 24, // no token in Figma — level-1 left indent
131
136
  stripeW: 4, // no token in Figma — indicator stripe width
132
- colPadL: u("padding-medium", 12),
133
- colPadR: u("padding-tight", 8),
134
- collapseGap: u("padding-xxtight", 4),
137
+ colPadL: u("padding-medium"),
138
+ colPadR: u("padding-tight"),
139
+ collapseGap: u("padding-xxtight"),
135
140
  };
136
141
 
137
142
  // ─── IndicatorStripe ──────────────────────────────────────────────────────────
@@ -313,7 +318,7 @@ export function SideNavTooltip({ label, anchorRect, onMouseEnter, onMouseLeave }
313
318
  top: anchorRect.top + anchorRect.height / 2,
314
319
  zIndex: 1000, backgroundColor: T.surface.navLight,
315
320
  border: `0.5px solid ${c("stroke-static-neutral-faint")}`, borderRadius: 8,
316
- boxShadow: "2px 2px 8px 0px rgba(0,0,0,0.03)",
321
+ boxShadow: c2("--elevation-widget"),
317
322
  padding: "6px 8px", whiteSpace: "nowrap", pointerEvents: "auto",
318
323
  animation: "popoverInCentered var(--motion-duration-3) var(--motion-easing-spring) forwards" }}>
319
324
  <span style={{ fontFamily: "'Red Hat Text',sans-serif", fontWeight: 400,
@@ -352,7 +357,7 @@ export function CollapsedPopover({ item, onClick, anchorRect, onMouseEnter, onMo
352
357
  style={{ position: "fixed", left: anchorRect.right + 8, top: anchorRect.top,
353
358
  zIndex: 1000, backgroundColor: T.surface.navElevated,
354
359
  border: `0.5px solid ${c("stroke-static-neutral-faint")}`, borderRadius: 8,
355
- boxShadow: "2px 2px 8px 4px rgba(0,0,0,0.03)",
360
+ boxShadow: c2("--elevation-widget"),
356
361
  padding: 6, minWidth: 200, pointerEvents: "auto",
357
362
  animation: "popoverIn var(--motion-duration-3) var(--motion-easing-spring) forwards" }}>
358
363
  {/* Section label — Figma component 40006794-5977 */}
@@ -398,7 +403,7 @@ export function PopoverRow({ item, onClick, activeId }) {
398
403
  export function CollapseButton({ isSidebarCollapsed, onToggle, collapseIcon, expandIcon }) {
399
404
  const [h, setH] = useState(false);
400
405
  const labelColor = h ? T.text.navHover : T.text.navBase;
401
- const actionIconColor = T.foreground.actionSecondary; // #6b6b6b — always static, no hover change
406
+ const actionIconColor = T.icon.actionSecondary; // #6b6b6b — always static, no hover change
402
407
  return (
403
408
  <div style={{ width: "100%" }}>
404
409
  <div style={{ height: 1, backgroundColor: T.fill.infoSubtle, marginBottom: L.collapseGap }} />
@@ -458,7 +463,7 @@ export function CollapseButton({ isSidebarCollapsed, onToggle, collapseIcon, exp
458
463
  // Hidden on mobile (<768px) — TopNav hamburger is the sole toggle there.
459
464
  export function NavHeader({ isSidebarCollapsed, onToggle, collapseIcon, expandIcon }) {
460
465
  const [h, setH] = useState(false);
461
- const actionIconColor = T.foreground.actionSecondary; // #6b6b6b — always static
466
+ const actionIconColor = T.icon.actionSecondary; // #6b6b6b — always static
462
467
  return (
463
468
  <div style={{ width: "100%", flexShrink: 0 }}>
464
469
  <div onClick={onToggle} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
@@ -503,7 +508,7 @@ export function NavSectionLabel({ label }) {
503
508
  flexShrink: 0 }}>
504
509
  <span style={{ fontFamily: "'Red Hat Text',sans-serif", fontWeight: 600,
505
510
  fontSize: 11, lineHeight: "16px", letterSpacing: "0.6px",
506
- textTransform: "uppercase", color: T.text.secondarySubtle || "#606060",
511
+ textTransform: "uppercase", color: T.text.secondarySubtle,
507
512
  whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
508
513
  {label}
509
514
  </span>
@@ -863,7 +868,7 @@ function ChevUp({ size = 10, color }) {
863
868
  // right_panel_open — used on the collapse button when sidebar is EXPANDED (click to collapse)
864
869
  // Token: Foreground/Action/Secondary/Rest (#6b6b6b)
865
870
  // Figma component: SideBar Expand/Collapse, Type=Collapse, node 40006793:3783
866
- function RightPanelOpenIcon({ size = 12, color = T.foreground.actionSecondary }) {
871
+ function RightPanelOpenIcon({ size = 12, color = T.icon.actionSecondary }) {
867
872
  return (
868
873
  <svg width={size} height={size} viewBox="0 0 12 12" fill="none">
869
874
  <path d="M5.66667 7.86667V4.13333C5.66667 3.97778 5.6 3.87222 5.46667 3.81667C5.33333 3.76111 5.21111 3.78889 5.1 3.9L3.46667 5.53333C3.33333 5.66667 3.26667 5.82222 3.26667 6C3.26667 6.17778 3.33333 6.33333 3.46667 6.46667L5.1 8.1C5.21111 8.21111 5.33333 8.23889 5.46667 8.18333C5.6 8.12778 5.66667 8.02222 5.66667 7.86667ZM1.33333 12C0.966667 12 0.652778 11.8694 0.391667 11.6083C0.130556 11.3472 0 11.0333 0 10.6667V1.33333C0 0.966667 0.130556 0.652778 0.391667 0.391667C0.652778 0.130556 0.966667 0 1.33333 0H10.6667C11.0333 0 11.3472 0.130556 11.6083 0.391667C11.8694 0.652778 12 0.966667 12 1.33333V10.6667C12 11.0333 11.8694 11.3472 11.6083 11.6083C11.3472 11.8694 11.0333 12 10.6667 12H1.33333ZM8.66667 10.6667H10.6667V1.33333H8.66667V10.6667ZM7.33333 10.6667V1.33333H1.33333V10.6667H7.33333Z" fill={color} />
@@ -874,7 +879,7 @@ function RightPanelOpenIcon({ size = 12, color = T.foreground.actionSecondary })
874
879
  // left_panel_open — used on the collapse button when sidebar is COLLAPSED (click to expand)
875
880
  // Token: Foreground/Action/Secondary/Rest (#6b6b6b)
876
881
  // Figma component: SideBar Expand/Collapse, Type=Expand, node 40006793:3783
877
- function LeftPanelOpenIcon({ size = 12, color = T.foreground.actionSecondary }) {
882
+ function LeftPanelOpenIcon({ size = 12, color = T.icon.actionSecondary }) {
878
883
  return (
879
884
  <svg width={size} height={size} viewBox="0 0 12 12" fill="none">
880
885
  <path d="M6.33333 4.13333V7.86667C6.33333 8.02222 6.4 8.12778 6.53333 8.18333C6.66667 8.23889 6.78889 8.21111 6.9 8.1L8.53333 6.46667C8.66667 6.33333 8.73333 6.17778 8.73333 6C8.73333 5.82222 8.66667 5.66667 8.53333 5.53333L6.9 3.9C6.78889 3.78889 6.66667 3.76111 6.53333 3.81667C6.4 3.87222 6.33333 3.97778 6.33333 4.13333ZM1.33333 12C0.966667 12 0.652778 11.8694 0.391667 11.6083C0.130556 11.3472 0 11.0333 0 10.6667V1.33333C0 0.966667 0.130556 0.652778 0.391667 0.391667C0.652778 0.130556 0.966667 0 1.33333 0H10.6667C11.0333 0 11.3472 0.130556 11.6083 0.391667C11.8694 0.652778 12 0.966667 12 1.33333V10.6667C12 11.0333 11.8694 11.3472 11.6083 11.6083C11.3472 11.8694 11.0333 12 10.6667 12H1.33333ZM3.33333 10.6667V1.33333H1.33333V10.6667H3.33333ZM4.66667 10.6667H10.6667V1.33333H4.66667V10.6667Z" fill={color} />
package/dist/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **The colour contract is 210 names.** Your full working vocabulary is
4
4
  **360**. If you add up every declaration in this folder you get
5
- 1152 — that number is not the contract, and the table below says why.
5
+ 1152. That number is not the contract, and the table below says why.
6
6
 
7
7
  ## Link these, in this order
8
8
 
@@ -53,7 +53,7 @@ Use one when you specifically want a value that does not respond to the theme.
53
53
  ## Theming
54
54
 
55
55
  One name, two values, resolved by selector. Set `data-theme="midnight"` on `<html>`
56
- to flip the page, or on any element to flip just that subtree — it composes both ways,
56
+ to flip the page, or on any element to flip just that subtree. It composes both ways,
57
57
  so a light island can sit inside a dark island.
58
58
 
59
59
  Never put a mode in a property name. `--semantic-color-light-mode-*` came from
@@ -80,16 +80,106 @@ border-radius: calc(var(--semantic-layout-units-cornerradius-small) * 1px); /*
80
80
 
81
81
  The second is `calc(4px * 1px)`, which is not a length, so the browser drops it silently.
82
82
 
83
+ ## How to choose a token
84
+
85
+ Most of the cost of adopting this package is not installing it. It is deciding
86
+ which of the colour names belongs on something you already built. This is the
87
+ rule.
88
+
89
+ Both tiers carry a family (`neutral`, `brand`, `negative`) and an emphasis rung
90
+ (`faint`, `subtle`, `base`, `bold`, `strong`). Only one of them carries state.
91
+
92
+ | | what it means | example |
93
+ |---|---|---|
94
+ | Emphasis | how loud this element is. Chosen once, never changes. | a divider is `stroke-static-neutral-faint`, permanently |
95
+ | State | where an element is in an interaction right now. One element moves through all of them. | a button is `rest`, then `hover`, then `pressed` |
96
+
97
+ So the question is not how many values exist. `Static` has six rungs and is
98
+ still single-valued per element. The question is:
99
+
100
+ > Does this element's colour change because of something the user does to it?
101
+
102
+ Yes means **Action**, and you need its whole state set. No means **Static**, and
103
+ you pick one emphasis rung and stop.
104
+
105
+ As a procedure:
106
+
107
+ 1. Interactive? Action. Otherwise Static.
108
+ 2. Tier: a background is `fill`, text or an icon is `foreground`, a border or
109
+ outline is `stroke`.
110
+ 3. Family: `neutral`, `brand`, `negative`, `positive`, `info`, `attention`,
111
+ `severe`, or an `accent` hue.
112
+ 4. Emphasis rung, quietest to loudest: `faint`, `subtle`, `base`, `bold`,
113
+ `strong`.
114
+ 5. If Action, take `-rest`, `-hover`, `-pressed` together, plus `-disabled`.
115
+
116
+ ## What the names do not promise
117
+
118
+ The names are deliberately legible so they can assist mapping. The cost of that
119
+ legibility is that a name can read like a promise it is not making.
120
+
121
+ - **`primary` is not your primary button.** It means *a* primary action. This
122
+ package ships no button and has no opinion about yours. If your main call to
123
+ action is visually quiet, the loud primary token is the wrong one for it
124
+ however well the words line up.
125
+ - **A component-shaped name is not a component contract.** `fill-action-field-*`
126
+ describes a field-like surface. Nothing here constrains component anatomy.
127
+ - **Two names resolving to the same value are not interchangeable.** Some pairs
128
+ currently share a value in some themes. They mean different things and are
129
+ free to diverge in the next release. Choose by the rule above, not by which
130
+ value looks right today.
131
+ - **`-on-strong` and `-on-subtle` are pairing constraints, not shades.**
132
+ `foreground-static-brand-on-strong` means the foreground to use ON a strong
133
+ fill. It is a contrast guarantee about a combination. Using it on a light
134
+ surface is an accessibility failure, not a quiet variant.
135
+ - **Absence is sometimes deliberate.** There is no foreground rung lighter than
136
+ `#484848`, because everything lighter fails WCAG AA on white. A missing grey
137
+ is a refusal, not a gap. Report it rather than reaching for a primitive.
138
+
139
+ ## Why the architecture is shaped this way
140
+
141
+ Worth knowing, because it explains the shape rather than just stating it.
142
+
143
+ **One token library skins several codebases, products and UI libraries, and
144
+ there is no shared component library yet.** That single constraint sets the
145
+ whole design. The names have to be self-explanatory enough to help a developer
146
+ map an existing product onto them, without being so granular that the set
147
+ bloats and nobody adopts it. Everything below follows from that.
148
+
149
+ **Action and Static are separate tiers because state is the only axis Action
150
+ adds.** Both carry family and emphasis. When a component library exists, the
151
+ component will carry the context and this fork will stop being something anyone
152
+ picks by hand. Until then, the tier is what tells you whether a value has to
153
+ respond to a pointer.
154
+
155
+ **Modes live on the semantic tier, never in a name.** One name resolves to a
156
+ different value per brand theme (Amplify, NewCo) and per mode (Light, Dark), so
157
+ the colour contract is a few hundred names carrying several times that many
158
+ values. A brand or a mode in a property name means something has gone wrong;
159
+ `--semantic-color-light-mode-*` is retired and resolves to nothing.
160
+
161
+ **Primitives are published so that bindings resolve, not so that they get
162
+ applied.** Every primitive carries "Do not apply directly" in its own
163
+ description. If you find yourself naming a `--primitive-color-*`, the token you
164
+ want either exists under a semantic name or does not exist yet.
165
+
166
+ **If two names still look equally right, say which two.** A name that cannot be
167
+ chosen between is a defect here, not in your understanding. It is also the most
168
+ useful feedback a consuming team can send, because a mapping is invisible from
169
+ this side until someone reports it.
170
+
83
171
  ## Machine-readable
84
172
 
85
173
  `contract.json` lists every consumable name plus the per-file counts, so you can lint
86
- against it if you want the boundary enforced.
174
+ against it if you want the boundary enforced. It also carries a `guidance` block with
175
+ the choosing rule above in structured form, for a tool resolving a design onto these
176
+ names without a human in the loop.
87
177
 
88
178
  ## Motion is not in Figma
89
179
 
90
180
  The Variables panel has zero motion variables; `motion.css` is generated from
91
181
  `docs/design-system-spec.md` §2. Anyone rebuilding tokens from a Figma export gets no
92
- motion at all and no warning — consume the package instead.
182
+ motion at all and no warning, so consume the package instead.
93
183
 
94
184
  ---
95
185
 
@@ -349,16 +349,16 @@
349
349
  --primitive-color-saffron-75: #fee2b3;
350
350
  --primitive-color-saffron-100: #fed897;
351
351
  --primitive-color-saffron-150: #ffc864;
352
- --primitive-color-saffron-200: #eab655;
353
- --primitive-color-saffron-250: #d6a549;
354
- --primitive-color-saffron-300: #bf9342;
355
- --primitive-color-saffron-350: #aa843e;
356
- --primitive-color-saffron-400: #91723b;
357
- --primitive-color-saffron-500: #6d5936;
358
- --primitive-color-saffron-600: #4e422d;
359
- --primitive-color-saffron-700: #342d21;
360
- --primitive-color-saffron-800: #1d1912;
361
- --primitive-color-saffron-900: #050301;
352
+ --primitive-color-saffron-200: #efb44d;
353
+ --primitive-color-saffron-250: #dfa23e;
354
+ --primitive-color-saffron-300: #cb8e31;
355
+ --primitive-color-saffron-350: #b97e2b;
356
+ --primitive-color-saffron-400: #a26b26;
357
+ --primitive-color-saffron-500: #7c5324;
358
+ --primitive-color-saffron-600: #583e24;
359
+ --primitive-color-saffron-700: #3d2a19;
360
+ --primitive-color-saffron-800: #23170b;
361
+ --primitive-color-saffron-900: #0a0200;
362
362
  --primitive-color-saffron-150-16: rgba(255, 200, 100, 0.16);
363
363
  --primitive-color-saffron-150-24: rgba(255, 200, 100, 0.24);
364
364
  --primitive-color-saffron-150-36: rgba(255, 200, 100, 0.36);
@@ -68,11 +68,11 @@
68
68
  --semantic-color-fill-static-info-subtle: var(--primitive-color-amethyst-350-16);
69
69
  --semantic-color-fill-static-negative-strong: var(--primitive-color-red-400);
70
70
  --semantic-color-fill-static-negative-subtle: var(--primitive-color-red-300-16);
71
- --semantic-color-fill-static-neutral-base: var(--primitive-color-cool-neutral-600);
72
- --semantic-color-fill-static-neutral-faint: var(--primitive-color-cool-neutral-800);
71
+ --semantic-color-fill-static-neutral-base: var(--primitive-color-midnight-800);
72
+ --semantic-color-fill-static-neutral-faint: var(--primitive-color-midnight-900);
73
73
  --semantic-color-fill-static-neutral-mono: var(--primitive-color-cool-neutral-0);
74
- --semantic-color-fill-static-neutral-strong: var(--primitive-color-cool-neutral-400);
75
- --semantic-color-fill-static-neutral-subtle: var(--primitive-color-cool-neutral-700);
74
+ --semantic-color-fill-static-neutral-strong: var(--primitive-color-midnight-350);
75
+ --semantic-color-fill-static-neutral-subtle: var(--primitive-color-midnight-850);
76
76
  --semantic-color-fill-static-positive-strong: var(--primitive-color-green-250);
77
77
  --semantic-color-fill-static-positive-subtle: var(--primitive-color-green-350-16);
78
78
  --semantic-color-fill-static-severe-strong: var(--primitive-color-orange-200);
@@ -68,11 +68,11 @@
68
68
  --semantic-color-fill-static-info-subtle: var(--primitive-color-amethyst-50);
69
69
  --semantic-color-fill-static-negative-strong: var(--primitive-color-red-400);
70
70
  --semantic-color-fill-static-negative-subtle: var(--primitive-color-red-50);
71
- --semantic-color-fill-static-neutral-base: var(--primitive-color-cool-neutral-25);
72
- --semantic-color-fill-static-neutral-faint: var(--primitive-color-cool-neutral-5);
71
+ --semantic-color-fill-static-neutral-base: var(--primitive-color-warm-neutral-50);
72
+ --semantic-color-fill-static-neutral-faint: var(--primitive-color-warm-neutral-0);
73
73
  --semantic-color-fill-static-neutral-mono: var(--primitive-color-cool-neutral-0);
74
- --semantic-color-fill-static-neutral-strong: var(--primitive-color-cool-neutral-150);
75
- --semantic-color-fill-static-neutral-subtle: var(--primitive-color-cool-neutral-10);
74
+ --semantic-color-fill-static-neutral-strong: var(--primitive-color-warm-neutral-75);
75
+ --semantic-color-fill-static-neutral-subtle: var(--primitive-color-warm-neutral-25);
76
76
  --semantic-color-fill-static-positive-strong: var(--primitive-color-green-500);
77
77
  --semantic-color-fill-static-positive-subtle: var(--primitive-color-green-25);
78
78
  --semantic-color-fill-static-severe-strong: var(--primitive-color-orange-200);
@@ -3834,7 +3834,7 @@ const tokens = {
3834
3834
  ]
3835
3835
  },
3836
3836
  "primitive-color-saffron-200": {
3837
- "value": "#eab655",
3837
+ "value": "#efb44d",
3838
3838
  "type": "color",
3839
3839
  "path": [
3840
3840
  "primitive-color",
@@ -3844,7 +3844,7 @@ const tokens = {
3844
3844
  ]
3845
3845
  },
3846
3846
  "primitive-color-saffron-250": {
3847
- "value": "#d6a549",
3847
+ "value": "#dfa23e",
3848
3848
  "type": "color",
3849
3849
  "path": [
3850
3850
  "primitive-color",
@@ -3854,7 +3854,7 @@ const tokens = {
3854
3854
  ]
3855
3855
  },
3856
3856
  "primitive-color-saffron-300": {
3857
- "value": "#bf9342",
3857
+ "value": "#cb8e31",
3858
3858
  "type": "color",
3859
3859
  "path": [
3860
3860
  "primitive-color",
@@ -3864,7 +3864,7 @@ const tokens = {
3864
3864
  ]
3865
3865
  },
3866
3866
  "primitive-color-saffron-350": {
3867
- "value": "#aa843e",
3867
+ "value": "#b97e2b",
3868
3868
  "type": "color",
3869
3869
  "path": [
3870
3870
  "primitive-color",
@@ -3874,7 +3874,7 @@ const tokens = {
3874
3874
  ]
3875
3875
  },
3876
3876
  "primitive-color-saffron-400": {
3877
- "value": "#91723b",
3877
+ "value": "#a26b26",
3878
3878
  "type": "color",
3879
3879
  "path": [
3880
3880
  "primitive-color",
@@ -3884,7 +3884,7 @@ const tokens = {
3884
3884
  ]
3885
3885
  },
3886
3886
  "primitive-color-saffron-500": {
3887
- "value": "#6d5936",
3887
+ "value": "#7c5324",
3888
3888
  "type": "color",
3889
3889
  "path": [
3890
3890
  "primitive-color",
@@ -3894,7 +3894,7 @@ const tokens = {
3894
3894
  ]
3895
3895
  },
3896
3896
  "primitive-color-saffron-600": {
3897
- "value": "#4e422d",
3897
+ "value": "#583e24",
3898
3898
  "type": "color",
3899
3899
  "path": [
3900
3900
  "primitive-color",
@@ -3904,7 +3904,7 @@ const tokens = {
3904
3904
  ]
3905
3905
  },
3906
3906
  "primitive-color-saffron-700": {
3907
- "value": "#342d21",
3907
+ "value": "#3d2a19",
3908
3908
  "type": "color",
3909
3909
  "path": [
3910
3910
  "primitive-color",
@@ -3914,7 +3914,7 @@ const tokens = {
3914
3914
  ]
3915
3915
  },
3916
3916
  "primitive-color-saffron-800": {
3917
- "value": "#1d1912",
3917
+ "value": "#23170b",
3918
3918
  "type": "color",
3919
3919
  "path": [
3920
3920
  "primitive-color",
@@ -3924,7 +3924,7 @@ const tokens = {
3924
3924
  ]
3925
3925
  },
3926
3926
  "primitive-color-saffron-900": {
3927
- "value": "#050301",
3927
+ "value": "#0a0200",
3928
3928
  "type": "color",
3929
3929
  "path": [
3930
3930
  "primitive-color",
@@ -5508,7 +5508,7 @@ const tokens = {
5508
5508
  ]
5509
5509
  },
5510
5510
  "semantic-color-light-fill-static-neutral-base": {
5511
- "value": "#f6f6f6",
5511
+ "value": "#f3f0ec",
5512
5512
  "type": "color",
5513
5513
  "path": [
5514
5514
  "semantic-color",
@@ -5520,7 +5520,7 @@ const tokens = {
5520
5520
  ]
5521
5521
  },
5522
5522
  "semantic-color-light-fill-static-neutral-faint": {
5523
- "value": "#fdfdfd",
5523
+ "value": "#fefefd",
5524
5524
  "type": "color",
5525
5525
  "path": [
5526
5526
  "semantic-color",
@@ -5544,7 +5544,7 @@ const tokens = {
5544
5544
  ]
5545
5545
  },
5546
5546
  "semantic-color-light-fill-static-neutral-strong": {
5547
- "value": "#b5b5b5",
5547
+ "value": "#e6e2dc",
5548
5548
  "type": "color",
5549
5549
  "path": [
5550
5550
  "semantic-color",
@@ -5556,7 +5556,7 @@ const tokens = {
5556
5556
  ]
5557
5557
  },
5558
5558
  "semantic-color-light-fill-static-neutral-subtle": {
5559
- "value": "#fafafa",
5559
+ "value": "#f9f7f5",
5560
5560
  "type": "color",
5561
5561
  "path": [
5562
5562
  "semantic-color",
@@ -6388,7 +6388,7 @@ const tokens = {
6388
6388
  ]
6389
6389
  },
6390
6390
  "semantic-color-light-foreground-static-attention-on-subtle": {
6391
- "value": "#342d21",
6391
+ "value": "#3d2a19",
6392
6392
  "type": "color",
6393
6393
  "path": [
6394
6394
  "semantic-color",
@@ -7068,7 +7068,7 @@ const tokens = {
7068
7068
  ]
7069
7069
  },
7070
7070
  "semantic-color-light-stroke-static-attention-strong": {
7071
- "value": "#aa843e",
7071
+ "value": "#b97e2b",
7072
7072
  "type": "color",
7073
7073
  "path": [
7074
7074
  "semantic-color",
@@ -8092,7 +8092,7 @@ const tokens = {
8092
8092
  ]
8093
8093
  },
8094
8094
  "semantic-color-dark-fill-static-neutral-base": {
8095
- "value": "#313131",
8095
+ "value": "#353a52",
8096
8096
  "type": "color",
8097
8097
  "path": [
8098
8098
  "semantic-color",
@@ -8104,7 +8104,7 @@ const tokens = {
8104
8104
  ]
8105
8105
  },
8106
8106
  "semantic-color-dark-fill-static-neutral-faint": {
8107
- "value": "#161616",
8107
+ "value": "#181b2b",
8108
8108
  "type": "color",
8109
8109
  "path": [
8110
8110
  "semantic-color",
@@ -8128,7 +8128,7 @@ const tokens = {
8128
8128
  ]
8129
8129
  },
8130
8130
  "semantic-color-dark-fill-static-neutral-strong": {
8131
- "value": "#606060",
8131
+ "value": "#868bad",
8132
8132
  "type": "color",
8133
8133
  "path": [
8134
8134
  "semantic-color",
@@ -8140,7 +8140,7 @@ const tokens = {
8140
8140
  ]
8141
8141
  },
8142
8142
  "semantic-color-dark-fill-static-neutral-subtle": {
8143
- "value": "#202020",
8143
+ "value": "#262a3e",
8144
8144
  "type": "color",
8145
8145
  "path": [
8146
8146
  "semantic-color",
@@ -9664,7 +9664,7 @@ const tokens = {
9664
9664
  ]
9665
9665
  },
9666
9666
  "semantic-color-dark-stroke-static-attention-subtle": {
9667
- "value": "#bf9342",
9667
+ "value": "#cb8e31",
9668
9668
  "type": "color",
9669
9669
  "path": [
9670
9670
  "semantic-color",
@@ -1,6 +1,6 @@
1
1
  {
2
- "$comment": "The names a consumer may use. Generated from the emitted CSS by scripts/build-contract.js — do not hand-edit. Lint against `contract` if you want the boundary enforced; nothing here blocks a primitive.",
3
- "version": "10.0.0",
2
+ "$comment": "The names a consumer may use. Generated from the emitted CSS by scripts/build-contract.js, do not hand-edit. Lint against `contract` if you want the boundary enforced; nothing here blocks a primitive.",
3
+ "version": "10.0.2",
4
4
  "generated": "2026-09-30",
5
5
  "counts": {
6
6
  "contract": 360,
@@ -73,6 +73,55 @@
73
73
  "role": "Breakpoint values."
74
74
  }
75
75
  },
76
+ "guidance": {
77
+ "why": "One token library skins several codebases, products and UI libraries, and there is no shared component library yet. The names must be legible enough to assist mapping without being so granular that the set bloats and adoption fails. Every other choice below follows from that constraint.",
78
+ "decide": {
79
+ "question": "Does this element's colour change because of something the user does to it?",
80
+ "yes": "Action. Take the whole state set: -rest, -hover, -pressed, plus -disabled.",
81
+ "no": "Static. Pick one emphasis rung and stop.",
82
+ "note": "Not how many values exist. Static has six rungs and is still single-valued per element: the rungs are a menu you choose from once, the states are a sequence one element walks through."
83
+ },
84
+ "axes": {
85
+ "tier": {
86
+ "fill": "a background",
87
+ "foreground": "text or an icon",
88
+ "stroke": "a border or outline"
89
+ },
90
+ "family": [
91
+ "neutral",
92
+ "brand",
93
+ "negative",
94
+ "positive",
95
+ "info",
96
+ "attention",
97
+ "severe",
98
+ "accent"
99
+ ],
100
+ "emphasisQuietestFirst": [
101
+ "faint",
102
+ "subtle",
103
+ "base",
104
+ "bold",
105
+ "strong"
106
+ ],
107
+ "stateOnlyOnAction": [
108
+ "rest",
109
+ "hover",
110
+ "pressed",
111
+ "disabled"
112
+ ]
113
+ },
114
+ "doesNotPromise": [
115
+ "`primary` means A primary action, not your primary button. This package ships no components.",
116
+ "A component-shaped name such as fill-action-field-* describes a surface, not a component contract.",
117
+ "Two names sharing a value today are not interchangeable and may diverge in the next release.",
118
+ "`-on-strong` and `-on-subtle` are contrast pairing constraints, not lightness variants. The prefix names what must be behind the foreground.",
119
+ "No foreground rung is lighter than #484848 because everything lighter fails WCAG AA on white. A missing grey is a refusal, not a gap."
120
+ ],
121
+ "modes": "One name resolves per brand theme (Amplify, NewCo) and per mode (Light, Dark). Never put a brand or a mode in a property name; --semantic-color-light-mode-* is retired and resolves to nothing.",
122
+ "primitives": "Published so that bindings resolve, not so that they get applied. Every primitive carries \"Do not apply directly\" in its own description.",
123
+ "ifAmbiguous": "If two names look equally right, that is a defect here rather than in your understanding. Report which two: a consumer's mapping is invisible from this side until someone says so."
124
+ },
76
125
  "contract": [
77
126
  "--breakpoints-desktop-1440px",
78
127
  "--breakpoints-desktop-1920px",
@@ -369,16 +369,16 @@
369
369
  --primitive-color-saffron-75: #fee2b3;
370
370
  --primitive-color-saffron-100: #fed897;
371
371
  --primitive-color-saffron-150: #ffc864;
372
- --primitive-color-saffron-200: #eab655;
373
- --primitive-color-saffron-250: #d6a549;
374
- --primitive-color-saffron-300: #bf9342;
375
- --primitive-color-saffron-350: #aa843e;
376
- --primitive-color-saffron-400: #91723b;
377
- --primitive-color-saffron-500: #6d5936;
378
- --primitive-color-saffron-600: #4e422d;
379
- --primitive-color-saffron-700: #342d21;
380
- --primitive-color-saffron-800: #1d1912;
381
- --primitive-color-saffron-900: #050301;
372
+ --primitive-color-saffron-200: #efb44d;
373
+ --primitive-color-saffron-250: #dfa23e;
374
+ --primitive-color-saffron-300: #cb8e31;
375
+ --primitive-color-saffron-350: #b97e2b;
376
+ --primitive-color-saffron-400: #a26b26;
377
+ --primitive-color-saffron-500: #7c5324;
378
+ --primitive-color-saffron-600: #583e24;
379
+ --primitive-color-saffron-700: #3d2a19;
380
+ --primitive-color-saffron-800: #23170b;
381
+ --primitive-color-saffron-900: #0a0200;
382
382
  --primitive-color-saffron-150-16: rgba(255, 200, 100, 0.16);
383
383
  --primitive-color-saffron-150-24: rgba(255, 200, 100, 0.24);
384
384
  --primitive-color-saffron-150-36: rgba(255, 200, 100, 0.36);
@@ -453,10 +453,10 @@
453
453
  --primitive-color-warm-neutral-500-70: rgba(87, 83, 78, 0.7);
454
454
  --primitive-color-warm-neutral-500-8: rgba(87, 83, 78, 0.08);
455
455
  --primitive-type-family-brand: Red Hat Text;
456
- --primitive-type-fontstyle-normal: Normal;
457
- --primitive-type-fontstyle-italic: Italic;
458
- --primitive-type-textdecoration-none: None;
459
- --primitive-type-textdecoration-underline: Underline;
456
+ --primitive-type-fontstyle-normal: normal;
457
+ --primitive-type-fontstyle-italic: italic;
458
+ --primitive-type-textdecoration-none: none;
459
+ --primitive-type-textdecoration-underline: underline;
460
460
  --primitive-type-size-10: 10px;
461
461
  --primitive-type-size-11: 11px;
462
462
  --primitive-type-size-12: 12px;