@primer/primitives 0.0.0-20260430114213 → 0.0.0-20260430122223

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.
Files changed (44) hide show
  1. package/DESIGN_TOKENS_GUIDE.md +28 -20
  2. package/DESIGN_TOKENS_SPEC.md +67 -0
  3. package/dist/build/platforms/css.js +22 -4
  4. package/dist/build/transformers/figmaAttributes.js +6 -4
  5. package/dist/build/transformers/transitionToCss.js +5 -1
  6. package/dist/css/functional/motion/motion.css +15 -0
  7. package/dist/css/functional/themes/dark-colorblind-high-contrast.css +54 -54
  8. package/dist/css/functional/themes/dark-colorblind.css +54 -54
  9. package/dist/css/functional/themes/dark-dimmed-high-contrast.css +54 -54
  10. package/dist/css/functional/themes/dark-dimmed.css +54 -54
  11. package/dist/css/functional/themes/dark-high-contrast.css +54 -54
  12. package/dist/css/functional/themes/dark-tritanopia-high-contrast.css +54 -54
  13. package/dist/css/functional/themes/dark-tritanopia.css +54 -54
  14. package/dist/css/functional/themes/dark.css +54 -54
  15. package/dist/css/functional/themes/light-colorblind-high-contrast.css +54 -54
  16. package/dist/css/functional/themes/light-colorblind.css +54 -54
  17. package/dist/css/functional/themes/light-high-contrast.css +54 -54
  18. package/dist/css/functional/themes/light-tritanopia-high-contrast.css +54 -54
  19. package/dist/css/functional/themes/light-tritanopia.css +54 -54
  20. package/dist/css/functional/themes/light.css +54 -54
  21. package/dist/css/primitives.css +1 -0
  22. package/dist/docs/functional/motion/motion.json +427 -0
  23. package/dist/fallbacks/functional/motion/motion.json +51 -0
  24. package/dist/internalCss/dark-colorblind-high-contrast.css +54 -54
  25. package/dist/internalCss/dark-colorblind.css +54 -54
  26. package/dist/internalCss/dark-dimmed-high-contrast.css +54 -54
  27. package/dist/internalCss/dark-dimmed.css +54 -54
  28. package/dist/internalCss/dark-high-contrast.css +54 -54
  29. package/dist/internalCss/dark-tritanopia-high-contrast.css +54 -54
  30. package/dist/internalCss/dark-tritanopia.css +54 -54
  31. package/dist/internalCss/dark.css +54 -54
  32. package/dist/internalCss/light-colorblind-high-contrast.css +54 -54
  33. package/dist/internalCss/light-colorblind.css +54 -54
  34. package/dist/internalCss/light-high-contrast.css +54 -54
  35. package/dist/internalCss/light-tritanopia-high-contrast.css +54 -54
  36. package/dist/internalCss/light-tritanopia.css +54 -54
  37. package/dist/internalCss/light.css +54 -54
  38. package/dist/removed/color.json +421 -0
  39. package/dist/styleLint/functional/motion/motion.json +427 -0
  40. package/package.json +16 -18
  41. package/src/tokens/functional/motion/motion.json5 +190 -0
  42. package/src/tokens/removed/color.json +421 -0
  43. package/dist/removed/removed.json +0 -749
  44. package/src/tokens/removed/removed.json +0 -749
@@ -65,18 +65,26 @@
65
65
 
66
66
  ### Motion
67
67
 
68
- | Keyword | Rule |
69
- | ------- | -------------------------------------------------------------- |
70
- | MUST | Use motion for interactive state changes (hover, focus, press) |
71
- | MUST | Keep animations ≤300ms for UI interactions |
72
- | MUST | Respect `prefers-reduced-motion` media query |
73
- | MUST | Provide instant alternatives when motion is reduced |
74
- | SHOULD | Use 100-200ms for micro-interactions |
75
- | SHOULD | Use 200-300ms for state changes |
76
- | NEVER | Exceed 500ms for UI interactions |
77
- | NEVER | Use motion purely for decoration |
78
- | NEVER | Create indefinitely looping motion without user control |
79
- | NEVER | Rely solely on motion to convey information |
68
+ ```
69
+ --motion-[property]-[semantic]
70
+ ├── property: duration | easing | transition
71
+ └── semantic: micro | short | medium | long (duration)
72
+ hover | enter | exit | move | linear (easing)
73
+ hover | stateChange | enter | exit (transition)
74
+ ```
75
+
76
+ | Keyword | Rule |
77
+ | ------- | -------------------------------------------------------------------------- |
78
+ | MUST | Use `motion.transition.*` tokens for interactive state changes |
79
+ | MUST | Keep animations ≤`motion.duration.medium` (300ms) for UI interactions |
80
+ | MUST | Respect `prefers-reduced-motion` media query |
81
+ | MUST | Provide instant alternatives when motion is reduced |
82
+ | SHOULD | Use `motion.duration.micro` (100ms) for hover and focus micro-interactions |
83
+ | SHOULD | Use `motion.duration.short` (200ms) for state changes |
84
+ | NEVER | Exceed `motion.duration.long` (500ms) for UI interactions |
85
+ | NEVER | Use motion purely for decoration |
86
+ | NEVER | Create indefinitely looping motion without user control |
87
+ | NEVER | Rely solely on motion to convey information |
80
88
 
81
89
  ### Typography
82
90
 
@@ -126,10 +134,10 @@
126
134
 
127
135
  ## Decision Tree: Easing Selection
128
136
 
129
- 1. Is element entering/exiting viewport? → ease-out (default)
130
- 2. Is element moving/morphing on screen? → ease-in-out
131
- 3. Is this a hover state change? → ease
132
- 4. Is this constant motion (loaders)? → linear
137
+ 1. Is element entering/exiting viewport? → `motion.easing.enter` / `motion.easing.exit`
138
+ 2. Is element moving/morphing on screen? → `motion.easing.move`
139
+ 3. Is this a hover state change? → `motion.easing.hover`
140
+ 4. Is this constant motion (loaders)? → `motion.easing.linear`
133
141
 
134
142
  ---
135
143
 
@@ -148,11 +156,11 @@
148
156
  font: var(--text-body-shorthand-medium);
149
157
  cursor: pointer;
150
158
 
151
- /* Motion: MUST be <300ms */
159
+ /* Motion: Use functional motion tokens */
152
160
  transition:
153
- background-color 150ms ease,
154
- box-shadow 150ms ease,
155
- transform 100ms ease;
161
+ background-color var(--motion-transition-hover),
162
+ box-shadow var(--motion-transition-hover),
163
+ transform var(--motion-transition-hover);
156
164
  }
157
165
 
158
166
  /* State: Hover */
@@ -429,6 +429,73 @@ Display font stack for headings and titles. Same as sansSerif but semantically d
429
429
  **U:** display-text, heading, title
430
430
  **R:** Use for headings and display text. Prefer over sansSerif for titles.
431
431
 
432
+ ## Motion
433
+
434
+ ### motion-duration-long
435
+ Longer duration for complex multi-step animations or large-scale layout shifts. Use sparingly.
436
+ **U:** complex-animation, layout-shift, multi-step
437
+ **R:** Use sparingly for complex animations. NEVER use for simple UI interactions.
438
+
439
+ ### motion-duration-medium
440
+ Standard duration for elements entering or exiting the viewport, such as modals and dropdowns.
441
+ **U:** dropdown-appear, modal-open, tooltip-show
442
+ **R:** Use for elements entering or leaving the viewport. Maximum recommended duration for UI interactions.
443
+
444
+ ### motion-duration-micro
445
+ Fast micro-interactions like hover, focus ring, and color shifts.
446
+ **U:** color-shift, focus-ring, hover-transition
447
+ **R:** Use for instantaneous feedback on hover and focus states.
448
+
449
+ ### motion-duration-short
450
+ Quick transitions for state changes like expand/collapse, toggles, and visibility changes.
451
+ **U:** expand-collapse, toggle, visibility-change
452
+ **R:** Use for interactive state changes that need to feel responsive.
453
+
454
+ ### motion-easing-enter
455
+ Decelerating easing for elements entering the viewport or appearing on screen.
456
+ **U:** element-appearing, enter-animation, modal-open
457
+ **R:** RECOMMENDED default for enter animations. Element decelerates into its final position.
458
+
459
+ ### motion-easing-exit
460
+ Accelerating easing for elements exiting the viewport or leaving the screen.
461
+ **U:** element-leaving, exit-animation, modal-close
462
+ **R:** Use for elements leaving the viewport. Element accelerates away.
463
+
464
+ ### motion-easing-hover
465
+ Easing for hover state changes and micro-interactions.
466
+ **U:** button-hover, hover-state, micro-interaction
467
+ **R:** Use for hover state changes.
468
+
469
+ ### motion-easing-linear
470
+ Constant motion with no acceleration. Use for continuous animations like progress bars or loaders.
471
+ **U:** continuous-animation, loader, progress-bar
472
+ **R:** Use only for constant, uninterrupted motion.
473
+
474
+ ### motion-easing-move
475
+ Smooth easing for elements moving or morphing within the viewport.
476
+ **U:** morph-animation, position-change, size-change
477
+ **R:** Use for elements that move or change shape on screen.
478
+
479
+ ### motion-transition-enter
480
+ Transition for elements entering the viewport, such as modals, dropdowns, and tooltips.
481
+ **U:** dropdown-appear, modal-open, tooltip-show
482
+ **R:** Use for elements appearing on screen. Element decelerates into final position.
483
+
484
+ ### motion-transition-exit
485
+ Transition for elements exiting the viewport, such as closing modals and dismissing dropdowns.
486
+ **U:** dropdown-dismiss, modal-close, tooltip-hide
487
+ **R:** Use for elements leaving the screen. Shorter than enter to feel snappy.
488
+
489
+ ### motion-transition-hover
490
+ Transition for hover state changes on interactive elements like buttons and links.
491
+ **U:** button-hover, interactive-hover, link-hover
492
+ **R:** Use for all hover state transitions. Keeps interactions feeling instantaneous.
493
+
494
+ ### motion-transition-stateChange
495
+ Transition for state changes like toggles, expand/collapse, and visibility changes.
496
+ **U:** accordion, expand-collapse, toggle
497
+ **R:** Use for interactive elements that change between states.
498
+
432
499
  ## Overlay
433
500
 
434
501
  Tokens for modals, dialogs, popovers, and dropdown menus.
@@ -1,5 +1,23 @@
1
1
  import { isFromFile, isSource } from '../filters/index.js';
2
2
  import { outputReferencesTransformed, outputReferencesFilter } from 'style-dictionary/utils';
3
+ /**
4
+ * Determines whether a token's value should use CSS variable references.
5
+ *
6
+ * For most tokens, we check both that referenced tokens are in the current output
7
+ * (outputReferencesFilter) and that the string replacement is valid (outputReferencesTransformed).
8
+ *
9
+ * Composite border tokens need special handling because:
10
+ * 1. outputReferencesTransformed returns false for object original values
11
+ * 2. outputReferencesFilter returns false because width tokens are in a separate CSS file
12
+ * Style Dictionary's formatter correctly handles var() substitution in flattened composite strings,
13
+ * and the referenced tokens (borderColor.*, borderWidth.*, focus.outline-*) all exist as CSS variables at runtime.
14
+ */
15
+ const shouldOutputReferences = (token, platformOptions) => {
16
+ if (token.$type === 'border') {
17
+ return true;
18
+ }
19
+ return outputReferencesFilter(token, platformOptions) && outputReferencesTransformed(token, platformOptions);
20
+ };
3
21
  const getCssSelectors = (outputFile) => {
4
22
  // check for dark in the beginning of the output filename
5
23
  const lastSlash = outputFile.lastIndexOf('/');
@@ -54,7 +72,7 @@ export const css = (outputFile, prefix, buildPath, options) => {
54
72
  'src/tokens/functional/size/size-coarse.json5',
55
73
  'src/tokens/functional/size/size-fine.json5',
56
74
  ]),
57
- options: Object.assign({ showFileHeader: false, outputReferences: (token, platformOptions) => outputReferencesFilter(token, platformOptions) && outputReferencesTransformed(token, platformOptions), descriptions: false, queries: getCssSelectors(outputFile) }, options === null || options === void 0 ? void 0 : options.options),
75
+ options: Object.assign({ showFileHeader: false, outputReferences: shouldOutputReferences, descriptions: false, queries: getCssSelectors(outputFile) }, options === null || options === void 0 ? void 0 : options.options),
58
76
  },
59
77
  {
60
78
  destination: `${outputFile}`,
@@ -66,7 +84,7 @@ export const css = (outputFile, prefix, buildPath, options) => {
66
84
  'src/tokens/functional/size/size-coarse.json5',
67
85
  'src/tokens/functional/size/size-fine.json5',
68
86
  ]),
69
- options: Object.assign({ showFileHeader: false, outputReferences: (token, platformOptions) => outputReferencesFilter(token, platformOptions) && outputReferencesTransformed(token, platformOptions), descriptions: false }, options === null || options === void 0 ? void 0 : options.options),
87
+ options: Object.assign({ showFileHeader: false, outputReferences: shouldOutputReferences, descriptions: false }, options === null || options === void 0 ? void 0 : options.options),
70
88
  },
71
89
  {
72
90
  destination: `${outputFile}`,
@@ -74,7 +92,7 @@ export const css = (outputFile, prefix, buildPath, options) => {
74
92
  filter: token => isSource(token) && (options === null || options === void 0 ? void 0 : options.themed) !== true && token.$type === 'custom-viewportRange',
75
93
  options: {
76
94
  showFileHeader: false,
77
- outputReferences: (token, platformOptions) => outputReferencesFilter(token, platformOptions) && outputReferencesTransformed(token, platformOptions),
95
+ outputReferences: shouldOutputReferences,
78
96
  },
79
97
  },
80
98
  {
@@ -87,7 +105,7 @@ export const css = (outputFile, prefix, buildPath, options) => {
87
105
  ]),
88
106
  options: {
89
107
  descriptions: false,
90
- outputReferences: (token, platformOptions) => outputReferencesFilter(token, platformOptions) && outputReferencesTransformed(token, platformOptions),
108
+ outputReferences: shouldOutputReferences,
91
109
  showFileHeader: false,
92
110
  queries: [
93
111
  {
@@ -43,12 +43,14 @@ export const figmaAttributes = {
43
43
  name: 'figma/attributes',
44
44
  type: `attribute`,
45
45
  transform: (token, platform = {}) => {
46
- var _a, _b;
46
+ var _a, _b, _c;
47
47
  const { modeOverride, collection, scopes, group, codeSyntax } = ((_a = token.$extensions) === null || _a === void 0 ? void 0 : _a['org.primer.figma']) || {};
48
+ const collectionOverride = (_b = platform.options) === null || _b === void 0 ? void 0 : _b.collectionOverride;
49
+ const resolvedCollection = collectionOverride && collection && collection in collectionOverride ? collectionOverride[collection] : collection;
48
50
  return {
49
- mode: asArray((_b = platform.options) === null || _b === void 0 ? void 0 : _b.theme)[0] || modeOverride || 'default',
50
- collection,
51
- group: group || collection,
51
+ mode: asArray((_c = platform.options) === null || _c === void 0 ? void 0 : _c.theme)[0] || modeOverride || 'default',
52
+ collection: resolvedCollection,
53
+ group: group || resolvedCollection,
52
54
  scopes: getScopes(scopes),
53
55
  codeSyntax,
54
56
  };
@@ -22,6 +22,10 @@ export const transitionToCss = {
22
22
  }
23
23
  // check required properties
24
24
  checkRequiredTokenProperties(value, ['duration', 'timingFunction']);
25
- return `${value.duration} ${cubicBezierArrayToCss(value.timingFunction, token.path)} ${value.delay ? value.delay : ''}`.trim();
25
+ // timingFunction may already be a CSS string if resolved from a cubicBezier reference
26
+ const timing = typeof value.timingFunction === 'string'
27
+ ? value.timingFunction
28
+ : cubicBezierArrayToCss(value.timingFunction, token.path);
29
+ return `${value.duration} ${timing} ${value.delay ? value.delay : ''}`.trim();
26
30
  },
27
31
  };
@@ -0,0 +1,15 @@
1
+ :root {
2
+ --motion-duration-long: var(--base-duration-500); /** Longer duration for complex multi-step animations or large-scale layout shifts. Use sparingly. */
3
+ --motion-duration-medium: var(--base-duration-300); /** Standard duration for elements entering or exiting the viewport, such as modals and dropdowns. */
4
+ --motion-duration-micro: var(--base-duration-100); /** Fast micro-interactions like hover, focus ring, and color shifts. */
5
+ --motion-duration-short: var(--base-duration-200); /** Quick transitions for state changes like expand/collapse, toggles, and visibility changes. */
6
+ --motion-easing-enter: var(--base-easing-easeOut); /** Decelerating easing for elements entering the viewport or appearing on screen. */
7
+ --motion-easing-exit: var(--base-easing-easeIn); /** Accelerating easing for elements exiting the viewport or leaving the screen. */
8
+ --motion-easing-hover: var(--base-easing-ease); /** Easing for hover state changes and micro-interactions. */
9
+ --motion-easing-linear: var(--base-easing-linear); /** Constant motion with no acceleration. Use for continuous animations like progress bars or loaders. */
10
+ --motion-easing-move: var(--base-easing-easeInOut); /** Smooth easing for elements moving or morphing within the viewport. */
11
+ --motion-transition-enter: var(--motion-duration-medium) var(--motion-easing-enter); /** Transition for elements entering the viewport, such as modals, dropdowns, and tooltips. */
12
+ --motion-transition-exit: var(--motion-duration-short) var(--motion-easing-exit); /** Transition for elements exiting the viewport, such as closing modals and dismissing dropdowns. */
13
+ --motion-transition-hover: var(--motion-duration-micro) var(--motion-easing-hover); /** Transition for hover state changes on interactive elements like buttons and links. */
14
+ --motion-transition-stateChange: var(--motion-duration-short) var(--motion-easing-move); /** Transition for state changes like toggles, expand/collapse, and visibility changes. */
15
+ }
@@ -652,24 +652,24 @@
652
652
  --bgColor-upsell-emphasis: var(--bgColor-done-emphasis); /** Strong background for prominent upsell elements */
653
653
  --bgColor-upsell-muted: var(--bgColor-done-muted); /** Subtle background for upsell and promotional content */
654
654
  --bgColor-white: #ffffff; /** Pure white background */
655
- --border-accent-emphasis: 0.0625rem solid #409eff;
656
- --border-accent-muted: 0.0625rem solid #5cacff;
657
- --border-attention-emphasis: 0.0625rem solid #e09b13;
658
- --border-attention-muted: 0.0625rem solid #edaa27;
659
- --border-danger-emphasis: 0.0625rem solid #e7811d;
660
- --border-danger-muted: 0.0625rem solid #f48b25;
661
- --border-default: 0.0625rem solid #b7bdc8;
662
- --border-disabled: 0.0625rem solid #656c761a;
663
- --border-done-emphasis: 0.0625rem solid #b87fff;
664
- --border-done-muted: 0.0625rem solid #bf8fff;
665
- --border-severe-emphasis: 0.0625rem solid #e7811d;
666
- --border-severe-muted: 0.0625rem solid #e7811d;
667
- --border-sponsors-emphasis: 0.0625rem solid #ef6eb1;
668
- --border-sponsors-muted: 0.0625rem solid #f87cbd;
669
- --border-success-emphasis: 0.0625rem solid #409eff;
670
- --border-success-muted: 0.0625rem solid #5cacff;
671
- --border-translucent: 0.0625rem solid #9198a1; /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
672
- --border-transparent: 0.0625rem solid #00000000;
655
+ --border-accent-emphasis: var(--borderWidth-default) solid var(--borderColor-accent-emphasis);
656
+ --border-accent-muted: var(--borderWidth-default) solid var(--borderColor-accent-muted);
657
+ --border-attention-emphasis: var(--borderWidth-default) solid var(--borderColor-attention-emphasis);
658
+ --border-attention-muted: var(--borderWidth-default) solid var(--borderColor-attention-muted);
659
+ --border-danger-emphasis: var(--borderWidth-default) solid var(--borderColor-danger-emphasis);
660
+ --border-danger-muted: var(--borderWidth-default) solid var(--borderColor-danger-muted);
661
+ --border-default: var(--borderWidth-default) solid var(--borderColor-default);
662
+ --border-disabled: var(--borderWidth-default) solid var(--borderColor-disabled);
663
+ --border-done-emphasis: var(--borderWidth-default) solid var(--borderColor-done-emphasis);
664
+ --border-done-muted: var(--borderWidth-default) solid var(--borderColor-done-muted);
665
+ --border-severe-emphasis: var(--borderWidth-default) solid var(--borderColor-severe-emphasis);
666
+ --border-severe-muted: var(--borderWidth-default) solid var(--borderColor-severe-muted);
667
+ --border-sponsors-emphasis: var(--borderWidth-default) solid var(--borderColor-sponsors-emphasis);
668
+ --border-sponsors-muted: var(--borderWidth-default) solid var(--borderColor-sponsors-muted);
669
+ --border-success-emphasis: var(--borderWidth-default) solid var(--borderColor-success-emphasis);
670
+ --border-success-muted: var(--borderWidth-default) solid var(--borderColor-success-muted);
671
+ --border-translucent: var(--borderWidth-default) solid var(--borderColor-translucent); /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
672
+ --border-transparent: var(--borderWidth-default) solid var(--borderColor-transparent);
673
673
  --borderColor-closed-muted: var(--borderColor-default); /** Subtle border for closed state indicators */
674
674
  --borderColor-draft-muted: var(--borderColor-default); /** Subtle border for draft state indicators */
675
675
  --borderColor-emphasis: var(--borderColor-default); /** Strong border for emphasis and visual weight */
@@ -808,13 +808,13 @@
808
808
  --avatar-borderColor: var(--borderColor-emphasis);
809
809
  --border-closed-emphasis: var(--border-danger-emphasis);
810
810
  --border-closed-muted: var(--border-danger-muted);
811
- --border-draft-muted: 0.0625rem solid #b7bdc8;
812
- --border-emphasis: 0.0625rem solid #b7bdc8;
813
- --border-muted: 0.0625rem solid #b7bdc8;
811
+ --border-draft-muted: var(--borderWidth-default) solid var(--borderColor-draft-muted);
812
+ --border-emphasis: var(--borderWidth-default) solid var(--borderColor-emphasis);
813
+ --border-muted: var(--borderWidth-default) solid var(--borderColor-muted);
814
814
  --border-open-emphasis: var(--border-success-emphasis);
815
815
  --border-open-muted: var(--border-success-muted);
816
- --border-upsell-emphasis: 0.0625rem solid #b87fff;
817
- --border-upsell-muted: 0.0625rem solid #bf8fff;
816
+ --border-upsell-emphasis: var(--borderWidth-default) solid var(--borderColor-upsell-emphasis);
817
+ --border-upsell-muted: var(--borderWidth-default) solid var(--borderColor-upsell-muted);
818
818
  --borderColor-closed-emphasis: var(--borderColor-emphasis); /** Strong border for closed state badges */
819
819
  --borderColor-neutral-emphasis: var(--borderColor-emphasis); /** Strong neutral semantic border */
820
820
  --borderColor-neutral-muted: var(--borderColor-muted); /** Subtle neutral semantic border */
@@ -876,7 +876,7 @@
876
876
  --diffBlob-expander-iconColor: var(--fgColor-default);
877
877
  --diffBlob-hunkNum-fgColor-hover: var(--fgColor-onEmphasis);
878
878
  --diffBlob-hunkNum-fgColor-rest: var(--fgColor-default);
879
- --focus-outline: 0.125rem solid #409eff; /** Focus ring outline for keyboard navigation and accessibility. */
879
+ --focus-outline: var(--focus-outline-width) solid var(--focus-outline-color); /** Focus ring outline for keyboard navigation and accessibility. */
880
880
  --focus-outlineColor: var(--focus-outline-color); /** Deprecated. Use focus.outline-color instead. */
881
881
  --page-header-bgColor: var(--bgColor-default);
882
882
  --progressBar-track-bgColor: var(--bgColor-inverse);
@@ -886,8 +886,8 @@
886
886
  --shadow-floating-xlarge: 0 0 0 1px #b7bdc8, 0 32px 64px 0 #010409; /** Extra large floating shadow for full-screen overlays and sheets */
887
887
  --tooltip-bgColor: var(--bgColor-inverse);
888
888
  --tooltip-fgColor: var(--fgColor-onInverse);
889
- --border-neutral-emphasis: 0.0625rem solid #b7bdc8;
890
- --border-neutral-muted: 0.0625rem solid #b7bdc8;
889
+ --border-neutral-emphasis: var(--borderWidth-default) solid var(--borderColor-neutral-emphasis);
890
+ --border-neutral-muted: var(--borderWidth-default) solid var(--borderColor-neutral-muted);
891
891
  --borderColor-draft-emphasis: var(--borderColor-neutral-emphasis); /** Strong border for draft state badges */
892
892
  --button-default-borderColor-active: var(--button-default-borderColor-rest);
893
893
  --button-default-borderColor-hover: var(--button-default-borderColor-rest);
@@ -901,7 +901,7 @@
901
901
  --controlKnob-borderColor-rest: var(--control-borderColor-emphasis);
902
902
  --progressBar-track-borderColor: var(--progressBar-track-bgColor);
903
903
  --underlineNav-borderColor-hover: var(--borderColor-neutral-muted);
904
- --border-draft-emphasis: 0.0625rem solid #b7bdc8;
904
+ --border-draft-emphasis: var(--borderWidth-default) solid var(--borderColor-draft-emphasis);
905
905
  --button-outline-borderColor-hover: var(--button-default-borderColor-hover);
906
906
  --button-outline-borderColor-active: var(--button-outline-borderColor-hover);
907
907
  }
@@ -1555,24 +1555,24 @@
1555
1555
  --bgColor-upsell-emphasis: var(--bgColor-done-emphasis); /** Strong background for prominent upsell elements */
1556
1556
  --bgColor-upsell-muted: var(--bgColor-done-muted); /** Subtle background for upsell and promotional content */
1557
1557
  --bgColor-white: #ffffff; /** Pure white background */
1558
- --border-accent-emphasis: 0.0625rem solid #409eff;
1559
- --border-accent-muted: 0.0625rem solid #5cacff;
1560
- --border-attention-emphasis: 0.0625rem solid #e09b13;
1561
- --border-attention-muted: 0.0625rem solid #edaa27;
1562
- --border-danger-emphasis: 0.0625rem solid #e7811d;
1563
- --border-danger-muted: 0.0625rem solid #f48b25;
1564
- --border-default: 0.0625rem solid #b7bdc8;
1565
- --border-disabled: 0.0625rem solid #656c761a;
1566
- --border-done-emphasis: 0.0625rem solid #b87fff;
1567
- --border-done-muted: 0.0625rem solid #bf8fff;
1568
- --border-severe-emphasis: 0.0625rem solid #e7811d;
1569
- --border-severe-muted: 0.0625rem solid #e7811d;
1570
- --border-sponsors-emphasis: 0.0625rem solid #ef6eb1;
1571
- --border-sponsors-muted: 0.0625rem solid #f87cbd;
1572
- --border-success-emphasis: 0.0625rem solid #409eff;
1573
- --border-success-muted: 0.0625rem solid #5cacff;
1574
- --border-translucent: 0.0625rem solid #9198a1; /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
1575
- --border-transparent: 0.0625rem solid #00000000;
1558
+ --border-accent-emphasis: var(--borderWidth-default) solid var(--borderColor-accent-emphasis);
1559
+ --border-accent-muted: var(--borderWidth-default) solid var(--borderColor-accent-muted);
1560
+ --border-attention-emphasis: var(--borderWidth-default) solid var(--borderColor-attention-emphasis);
1561
+ --border-attention-muted: var(--borderWidth-default) solid var(--borderColor-attention-muted);
1562
+ --border-danger-emphasis: var(--borderWidth-default) solid var(--borderColor-danger-emphasis);
1563
+ --border-danger-muted: var(--borderWidth-default) solid var(--borderColor-danger-muted);
1564
+ --border-default: var(--borderWidth-default) solid var(--borderColor-default);
1565
+ --border-disabled: var(--borderWidth-default) solid var(--borderColor-disabled);
1566
+ --border-done-emphasis: var(--borderWidth-default) solid var(--borderColor-done-emphasis);
1567
+ --border-done-muted: var(--borderWidth-default) solid var(--borderColor-done-muted);
1568
+ --border-severe-emphasis: var(--borderWidth-default) solid var(--borderColor-severe-emphasis);
1569
+ --border-severe-muted: var(--borderWidth-default) solid var(--borderColor-severe-muted);
1570
+ --border-sponsors-emphasis: var(--borderWidth-default) solid var(--borderColor-sponsors-emphasis);
1571
+ --border-sponsors-muted: var(--borderWidth-default) solid var(--borderColor-sponsors-muted);
1572
+ --border-success-emphasis: var(--borderWidth-default) solid var(--borderColor-success-emphasis);
1573
+ --border-success-muted: var(--borderWidth-default) solid var(--borderColor-success-muted);
1574
+ --border-translucent: var(--borderWidth-default) solid var(--borderColor-translucent); /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
1575
+ --border-transparent: var(--borderWidth-default) solid var(--borderColor-transparent);
1576
1576
  --borderColor-closed-muted: var(--borderColor-default); /** Subtle border for closed state indicators */
1577
1577
  --borderColor-draft-muted: var(--borderColor-default); /** Subtle border for draft state indicators */
1578
1578
  --borderColor-emphasis: var(--borderColor-default); /** Strong border for emphasis and visual weight */
@@ -1711,13 +1711,13 @@
1711
1711
  --avatar-borderColor: var(--borderColor-emphasis);
1712
1712
  --border-closed-emphasis: var(--border-danger-emphasis);
1713
1713
  --border-closed-muted: var(--border-danger-muted);
1714
- --border-draft-muted: 0.0625rem solid #b7bdc8;
1715
- --border-emphasis: 0.0625rem solid #b7bdc8;
1716
- --border-muted: 0.0625rem solid #b7bdc8;
1714
+ --border-draft-muted: var(--borderWidth-default) solid var(--borderColor-draft-muted);
1715
+ --border-emphasis: var(--borderWidth-default) solid var(--borderColor-emphasis);
1716
+ --border-muted: var(--borderWidth-default) solid var(--borderColor-muted);
1717
1717
  --border-open-emphasis: var(--border-success-emphasis);
1718
1718
  --border-open-muted: var(--border-success-muted);
1719
- --border-upsell-emphasis: 0.0625rem solid #b87fff;
1720
- --border-upsell-muted: 0.0625rem solid #bf8fff;
1719
+ --border-upsell-emphasis: var(--borderWidth-default) solid var(--borderColor-upsell-emphasis);
1720
+ --border-upsell-muted: var(--borderWidth-default) solid var(--borderColor-upsell-muted);
1721
1721
  --borderColor-closed-emphasis: var(--borderColor-emphasis); /** Strong border for closed state badges */
1722
1722
  --borderColor-neutral-emphasis: var(--borderColor-emphasis); /** Strong neutral semantic border */
1723
1723
  --borderColor-neutral-muted: var(--borderColor-muted); /** Subtle neutral semantic border */
@@ -1779,7 +1779,7 @@
1779
1779
  --diffBlob-expander-iconColor: var(--fgColor-default);
1780
1780
  --diffBlob-hunkNum-fgColor-hover: var(--fgColor-onEmphasis);
1781
1781
  --diffBlob-hunkNum-fgColor-rest: var(--fgColor-default);
1782
- --focus-outline: 0.125rem solid #409eff; /** Focus ring outline for keyboard navigation and accessibility. */
1782
+ --focus-outline: var(--focus-outline-width) solid var(--focus-outline-color); /** Focus ring outline for keyboard navigation and accessibility. */
1783
1783
  --focus-outlineColor: var(--focus-outline-color); /** Deprecated. Use focus.outline-color instead. */
1784
1784
  --page-header-bgColor: var(--bgColor-default);
1785
1785
  --progressBar-track-bgColor: var(--bgColor-inverse);
@@ -1789,8 +1789,8 @@
1789
1789
  --shadow-floating-xlarge: 0 0 0 1px #b7bdc8, 0 32px 64px 0 #010409; /** Extra large floating shadow for full-screen overlays and sheets */
1790
1790
  --tooltip-bgColor: var(--bgColor-inverse);
1791
1791
  --tooltip-fgColor: var(--fgColor-onInverse);
1792
- --border-neutral-emphasis: 0.0625rem solid #b7bdc8;
1793
- --border-neutral-muted: 0.0625rem solid #b7bdc8;
1792
+ --border-neutral-emphasis: var(--borderWidth-default) solid var(--borderColor-neutral-emphasis);
1793
+ --border-neutral-muted: var(--borderWidth-default) solid var(--borderColor-neutral-muted);
1794
1794
  --borderColor-draft-emphasis: var(--borderColor-neutral-emphasis); /** Strong border for draft state badges */
1795
1795
  --button-default-borderColor-active: var(--button-default-borderColor-rest);
1796
1796
  --button-default-borderColor-hover: var(--button-default-borderColor-rest);
@@ -1804,7 +1804,7 @@
1804
1804
  --controlKnob-borderColor-rest: var(--control-borderColor-emphasis);
1805
1805
  --progressBar-track-borderColor: var(--progressBar-track-bgColor);
1806
1806
  --underlineNav-borderColor-hover: var(--borderColor-neutral-muted);
1807
- --border-draft-emphasis: 0.0625rem solid #b7bdc8;
1807
+ --border-draft-emphasis: var(--borderWidth-default) solid var(--borderColor-draft-emphasis);
1808
1808
  --button-outline-borderColor-hover: var(--button-default-borderColor-hover);
1809
1809
  --button-outline-borderColor-active: var(--button-outline-borderColor-hover);
1810
1810
  }
@@ -671,24 +671,24 @@
671
671
  --bgColor-upsell-emphasis: var(--bgColor-done-emphasis); /** Strong background for prominent upsell elements */
672
672
  --bgColor-upsell-muted: var(--bgColor-done-muted); /** Subtle background for upsell and promotional content */
673
673
  --bgColor-white: #ffffff; /** Pure white background */
674
- --border-accent-emphasis: 0.0625rem solid #1f6feb;
675
- --border-accent-muted: 0.0625rem solid #388bfd66;
676
- --border-attention-emphasis: 0.0625rem solid #9e6a03;
677
- --border-attention-muted: 0.0625rem solid #bb800966;
678
- --border-danger-emphasis: 0.0625rem solid #bd561d;
679
- --border-danger-muted: 0.0625rem solid #db6d2866;
680
- --border-default: 0.0625rem solid #3d444d;
681
- --border-disabled: 0.0625rem solid #656c761a;
682
- --border-done-emphasis: 0.0625rem solid #8957e5;
683
- --border-done-muted: 0.0625rem solid #ab7df866;
684
- --border-emphasis: 0.0625rem solid #656c76;
685
- --border-severe-emphasis: 0.0625rem solid #bd561d;
686
- --border-severe-muted: 0.0625rem solid #db6d2866;
687
- --border-sponsors-emphasis: 0.0625rem solid #bf4b8a;
688
- --border-sponsors-muted: 0.0625rem solid #db61a266;
689
- --border-success-emphasis: 0.0625rem solid #1f6feb;
690
- --border-success-muted: 0.0625rem solid #388bfd66;
691
- --border-transparent: 0.0625rem solid #00000000;
674
+ --border-accent-emphasis: var(--borderWidth-default) solid var(--borderColor-accent-emphasis);
675
+ --border-accent-muted: var(--borderWidth-default) solid var(--borderColor-accent-muted);
676
+ --border-attention-emphasis: var(--borderWidth-default) solid var(--borderColor-attention-emphasis);
677
+ --border-attention-muted: var(--borderWidth-default) solid var(--borderColor-attention-muted);
678
+ --border-danger-emphasis: var(--borderWidth-default) solid var(--borderColor-danger-emphasis);
679
+ --border-danger-muted: var(--borderWidth-default) solid var(--borderColor-danger-muted);
680
+ --border-default: var(--borderWidth-default) solid var(--borderColor-default);
681
+ --border-disabled: var(--borderWidth-default) solid var(--borderColor-disabled);
682
+ --border-done-emphasis: var(--borderWidth-default) solid var(--borderColor-done-emphasis);
683
+ --border-done-muted: var(--borderWidth-default) solid var(--borderColor-done-muted);
684
+ --border-emphasis: var(--borderWidth-default) solid var(--borderColor-emphasis);
685
+ --border-severe-emphasis: var(--borderWidth-default) solid var(--borderColor-severe-emphasis);
686
+ --border-severe-muted: var(--borderWidth-default) solid var(--borderColor-severe-muted);
687
+ --border-sponsors-emphasis: var(--borderWidth-default) solid var(--borderColor-sponsors-emphasis);
688
+ --border-sponsors-muted: var(--borderWidth-default) solid var(--borderColor-sponsors-muted);
689
+ --border-success-emphasis: var(--borderWidth-default) solid var(--borderColor-success-emphasis);
690
+ --border-success-muted: var(--borderWidth-default) solid var(--borderColor-success-muted);
691
+ --border-transparent: var(--borderWidth-default) solid var(--borderColor-transparent);
692
692
  --borderColor-closed-emphasis: var(--borderColor-emphasis); /** Strong border for closed state badges */
693
693
  --borderColor-closed-muted: #3d444d66; /** Subtle border for closed state indicators */
694
694
  --borderColor-draft-muted: #3d444d66; /** Subtle border for draft state indicators */
@@ -830,14 +830,14 @@
830
830
  --avatar-borderColor: var(--borderColor-translucent);
831
831
  --border-closed-emphasis: var(--border-danger-emphasis);
832
832
  --border-closed-muted: var(--border-danger-muted);
833
- --border-draft-muted: 0.0625rem solid #3d444d66;
834
- --border-muted: 0.0625rem solid #3d444db3;
835
- --border-neutral-emphasis: 0.0625rem solid #656c76;
833
+ --border-draft-muted: var(--borderWidth-default) solid var(--borderColor-draft-muted);
834
+ --border-muted: var(--borderWidth-default) solid var(--borderColor-muted);
835
+ --border-neutral-emphasis: var(--borderWidth-default) solid var(--borderColor-neutral-emphasis);
836
836
  --border-open-emphasis: var(--border-success-emphasis);
837
837
  --border-open-muted: var(--border-success-muted);
838
- --border-translucent: 0.0625rem solid #ffffff26; /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
839
- --border-upsell-emphasis: 0.0625rem solid #8957e5;
840
- --border-upsell-muted: 0.0625rem solid #ab7df866;
838
+ --border-translucent: var(--borderWidth-default) solid var(--borderColor-translucent); /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
839
+ --border-upsell-emphasis: var(--borderWidth-default) solid var(--borderColor-upsell-emphasis);
840
+ --border-upsell-muted: var(--borderWidth-default) solid var(--borderColor-upsell-muted);
841
841
  --borderColor-draft-emphasis: var(--borderColor-neutral-emphasis); /** Strong border for draft state badges */
842
842
  --borderColor-neutral-muted: var(--borderColor-muted); /** Subtle neutral semantic border */
843
843
  --button-danger-bgColor-disabled: var(--control-bgColor-disabled);
@@ -882,12 +882,12 @@
882
882
  --controlTrack-fgColor-disabled: var(--fgColor-onEmphasis);
883
883
  --dashboard-bgColor: var(--bgColor-inset);
884
884
  --diffBlob-hunkNum-fgColor-hover: var(--fgColor-onEmphasis);
885
- --focus-outline: 0.125rem solid #1f6feb; /** Focus ring outline for keyboard navigation and accessibility. */
885
+ --focus-outline: var(--focus-outline-width) solid var(--focus-outline-color); /** Focus ring outline for keyboard navigation and accessibility. */
886
886
  --focus-outlineColor: var(--focus-outline-color); /** Deprecated. Use focus.outline-color instead. */
887
887
  --overlay-borderColor: var(--borderColor-muted);
888
888
  --tooltip-fgColor: var(--fgColor-onEmphasis);
889
- --border-draft-emphasis: 0.0625rem solid #656c76;
890
- --border-neutral-muted: 0.0625rem solid #3d444db3;
889
+ --border-draft-emphasis: var(--borderWidth-default) solid var(--borderColor-draft-emphasis);
890
+ --border-neutral-muted: var(--borderWidth-default) solid var(--borderColor-neutral-muted);
891
891
  --button-danger-borderColor-hover: var(--button-primary-borderColor-rest);
892
892
  --button-default-borderColor-active: var(--button-default-borderColor-rest);
893
893
  --button-default-borderColor-hover: var(--button-default-borderColor-rest);
@@ -1574,24 +1574,24 @@
1574
1574
  --bgColor-upsell-emphasis: var(--bgColor-done-emphasis); /** Strong background for prominent upsell elements */
1575
1575
  --bgColor-upsell-muted: var(--bgColor-done-muted); /** Subtle background for upsell and promotional content */
1576
1576
  --bgColor-white: #ffffff; /** Pure white background */
1577
- --border-accent-emphasis: 0.0625rem solid #1f6feb;
1578
- --border-accent-muted: 0.0625rem solid #388bfd66;
1579
- --border-attention-emphasis: 0.0625rem solid #9e6a03;
1580
- --border-attention-muted: 0.0625rem solid #bb800966;
1581
- --border-danger-emphasis: 0.0625rem solid #bd561d;
1582
- --border-danger-muted: 0.0625rem solid #db6d2866;
1583
- --border-default: 0.0625rem solid #3d444d;
1584
- --border-disabled: 0.0625rem solid #656c761a;
1585
- --border-done-emphasis: 0.0625rem solid #8957e5;
1586
- --border-done-muted: 0.0625rem solid #ab7df866;
1587
- --border-emphasis: 0.0625rem solid #656c76;
1588
- --border-severe-emphasis: 0.0625rem solid #bd561d;
1589
- --border-severe-muted: 0.0625rem solid #db6d2866;
1590
- --border-sponsors-emphasis: 0.0625rem solid #bf4b8a;
1591
- --border-sponsors-muted: 0.0625rem solid #db61a266;
1592
- --border-success-emphasis: 0.0625rem solid #1f6feb;
1593
- --border-success-muted: 0.0625rem solid #388bfd66;
1594
- --border-transparent: 0.0625rem solid #00000000;
1577
+ --border-accent-emphasis: var(--borderWidth-default) solid var(--borderColor-accent-emphasis);
1578
+ --border-accent-muted: var(--borderWidth-default) solid var(--borderColor-accent-muted);
1579
+ --border-attention-emphasis: var(--borderWidth-default) solid var(--borderColor-attention-emphasis);
1580
+ --border-attention-muted: var(--borderWidth-default) solid var(--borderColor-attention-muted);
1581
+ --border-danger-emphasis: var(--borderWidth-default) solid var(--borderColor-danger-emphasis);
1582
+ --border-danger-muted: var(--borderWidth-default) solid var(--borderColor-danger-muted);
1583
+ --border-default: var(--borderWidth-default) solid var(--borderColor-default);
1584
+ --border-disabled: var(--borderWidth-default) solid var(--borderColor-disabled);
1585
+ --border-done-emphasis: var(--borderWidth-default) solid var(--borderColor-done-emphasis);
1586
+ --border-done-muted: var(--borderWidth-default) solid var(--borderColor-done-muted);
1587
+ --border-emphasis: var(--borderWidth-default) solid var(--borderColor-emphasis);
1588
+ --border-severe-emphasis: var(--borderWidth-default) solid var(--borderColor-severe-emphasis);
1589
+ --border-severe-muted: var(--borderWidth-default) solid var(--borderColor-severe-muted);
1590
+ --border-sponsors-emphasis: var(--borderWidth-default) solid var(--borderColor-sponsors-emphasis);
1591
+ --border-sponsors-muted: var(--borderWidth-default) solid var(--borderColor-sponsors-muted);
1592
+ --border-success-emphasis: var(--borderWidth-default) solid var(--borderColor-success-emphasis);
1593
+ --border-success-muted: var(--borderWidth-default) solid var(--borderColor-success-muted);
1594
+ --border-transparent: var(--borderWidth-default) solid var(--borderColor-transparent);
1595
1595
  --borderColor-closed-emphasis: var(--borderColor-emphasis); /** Strong border for closed state badges */
1596
1596
  --borderColor-closed-muted: #3d444d66; /** Subtle border for closed state indicators */
1597
1597
  --borderColor-draft-muted: #3d444d66; /** Subtle border for draft state indicators */
@@ -1733,14 +1733,14 @@
1733
1733
  --avatar-borderColor: var(--borderColor-translucent);
1734
1734
  --border-closed-emphasis: var(--border-danger-emphasis);
1735
1735
  --border-closed-muted: var(--border-danger-muted);
1736
- --border-draft-muted: 0.0625rem solid #3d444d66;
1737
- --border-muted: 0.0625rem solid #3d444db3;
1738
- --border-neutral-emphasis: 0.0625rem solid #656c76;
1736
+ --border-draft-muted: var(--borderWidth-default) solid var(--borderColor-draft-muted);
1737
+ --border-muted: var(--borderWidth-default) solid var(--borderColor-muted);
1738
+ --border-neutral-emphasis: var(--borderWidth-default) solid var(--borderColor-neutral-emphasis);
1739
1739
  --border-open-emphasis: var(--border-success-emphasis);
1740
1740
  --border-open-muted: var(--border-success-muted);
1741
- --border-translucent: 0.0625rem solid #ffffff26; /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
1742
- --border-upsell-emphasis: 0.0625rem solid #8957e5;
1743
- --border-upsell-muted: 0.0625rem solid #ab7df866;
1741
+ --border-translucent: var(--borderWidth-default) solid var(--borderColor-translucent); /** Semi-transparent border shorthand for overlays and layered elements. Border-specific token — no bgColor-translucent counterpart exists by design. */
1742
+ --border-upsell-emphasis: var(--borderWidth-default) solid var(--borderColor-upsell-emphasis);
1743
+ --border-upsell-muted: var(--borderWidth-default) solid var(--borderColor-upsell-muted);
1744
1744
  --borderColor-draft-emphasis: var(--borderColor-neutral-emphasis); /** Strong border for draft state badges */
1745
1745
  --borderColor-neutral-muted: var(--borderColor-muted); /** Subtle neutral semantic border */
1746
1746
  --button-danger-bgColor-disabled: var(--control-bgColor-disabled);
@@ -1785,12 +1785,12 @@
1785
1785
  --controlTrack-fgColor-disabled: var(--fgColor-onEmphasis);
1786
1786
  --dashboard-bgColor: var(--bgColor-inset);
1787
1787
  --diffBlob-hunkNum-fgColor-hover: var(--fgColor-onEmphasis);
1788
- --focus-outline: 0.125rem solid #1f6feb; /** Focus ring outline for keyboard navigation and accessibility. */
1788
+ --focus-outline: var(--focus-outline-width) solid var(--focus-outline-color); /** Focus ring outline for keyboard navigation and accessibility. */
1789
1789
  --focus-outlineColor: var(--focus-outline-color); /** Deprecated. Use focus.outline-color instead. */
1790
1790
  --overlay-borderColor: var(--borderColor-muted);
1791
1791
  --tooltip-fgColor: var(--fgColor-onEmphasis);
1792
- --border-draft-emphasis: 0.0625rem solid #656c76;
1793
- --border-neutral-muted: 0.0625rem solid #3d444db3;
1792
+ --border-draft-emphasis: var(--borderWidth-default) solid var(--borderColor-draft-emphasis);
1793
+ --border-neutral-muted: var(--borderWidth-default) solid var(--borderColor-neutral-muted);
1794
1794
  --button-danger-borderColor-hover: var(--button-primary-borderColor-rest);
1795
1795
  --button-default-borderColor-active: var(--button-default-borderColor-rest);
1796
1796
  --button-default-borderColor-hover: var(--button-default-borderColor-rest);