fluentui-webcomponents 0.0.1

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 (59) hide show
  1. package/AGENTS.md +212 -0
  2. package/README.md +99 -0
  3. package/components/avatar/fluent-avatar.css +481 -0
  4. package/components/avatar/fluent-avatar.js +80 -0
  5. package/components/badge/fluent-badge.css +289 -0
  6. package/components/badge/fluent-badge.js +20 -0
  7. package/components/breadcrumb/fluent-breadcrumb.css +29 -0
  8. package/components/breadcrumb/fluent-breadcrumb.js +33 -0
  9. package/components/breadcrumb-item/fluent-breadcrumb-item.css +70 -0
  10. package/components/breadcrumb-item/fluent-breadcrumb-item.js +77 -0
  11. package/components/button/fluent-button.css +265 -0
  12. package/components/button/fluent-button.js +326 -0
  13. package/components/card/fluent-card.css +85 -0
  14. package/components/card/fluent-card.js +21 -0
  15. package/components/checkbox/fluent-checkbox.css +171 -0
  16. package/components/checkbox/fluent-checkbox.js +294 -0
  17. package/components/dialog/fluent-dialog.css +82 -0
  18. package/components/dialog/fluent-dialog.js +137 -0
  19. package/components/divider/fluent-divider.css +124 -0
  20. package/components/divider/fluent-divider.js +14 -0
  21. package/components/image/fluent-image.css +73 -0
  22. package/components/image/fluent-image.js +36 -0
  23. package/components/label/fluent-label.css +49 -0
  24. package/components/label/fluent-label.js +61 -0
  25. package/components/link/fluent-link.css +72 -0
  26. package/components/link/fluent-link.js +109 -0
  27. package/components/menu/fluent-menu.css +57 -0
  28. package/components/menu/fluent-menu.js +202 -0
  29. package/components/menu-item/fluent-menu-item.css +152 -0
  30. package/components/menu-item/fluent-menu-item.js +177 -0
  31. package/components/popover/fluent-popover.css +95 -0
  32. package/components/popover/fluent-popover.js +93 -0
  33. package/components/radio/fluent-radio.css +123 -0
  34. package/components/radio/fluent-radio.js +257 -0
  35. package/components/select/fluent-select.css +194 -0
  36. package/components/select/fluent-select.js +245 -0
  37. package/components/slider/fluent-slider.css +199 -0
  38. package/components/slider/fluent-slider.js +438 -0
  39. package/components/spinner/fluent-spinner.css +160 -0
  40. package/components/spinner/fluent-spinner.js +30 -0
  41. package/components/switch/fluent-switch.css +154 -0
  42. package/components/switch/fluent-switch.js +260 -0
  43. package/components/text/fluent-text.css +128 -0
  44. package/components/text/fluent-text.js +21 -0
  45. package/components/text-input/fluent-text-input.css +227 -0
  46. package/components/text-input/fluent-text-input.js +298 -0
  47. package/components/textarea/fluent-textarea.css +227 -0
  48. package/components/textarea/fluent-textarea.js +400 -0
  49. package/components/tooltip/fluent-tooltip.css +65 -0
  50. package/components/tooltip/fluent-tooltip.js +102 -0
  51. package/components/tree/fluent-tree.css +16 -0
  52. package/components/tree/fluent-tree.js +167 -0
  53. package/components/tree-item/fluent-tree-item.css +147 -0
  54. package/components/tree-item/fluent-tree-item.js +163 -0
  55. package/core/fluent-element.js +34 -0
  56. package/gallery.html +492 -0
  57. package/package.json +19 -0
  58. package/theme/theme-picker.js +38 -0
  59. package/tokens.css +724 -0
package/tokens.css ADDED
@@ -0,0 +1,724 @@
1
+ /* ============================================================
2
+ Fluent UI Web Components — Design Tokens
3
+ Pure CSS, zero dependencies, zero build tools
4
+
5
+ Palette derivation ported from @microsoft/fast-colors
6
+ ColorPalette algorithm:
7
+ 1. baseScale = [0:white, 0.5:baseColor, 1:black]
8
+ 2. clipLight = 0.185 (trim 18.5% from light end)
9
+ clipDark = 0.16 (trim 16% from dark end)
10
+ 3. trimLight = baseScale.getColor(clipLight) // segPos 0.37
11
+ trimDark = baseScale.getColor(1-clipDark) // segPos 0.68
12
+ 4. Final scale: [0:trimLight, 0.5:baseColor, 1:trimDark]
13
+ 5. Generate stops at equal intervals between trimLight/trimDark
14
+ through baseColor
15
+
16
+ Dark mode: clipLight = 0 so trimLight = white (pure foreground)
17
+ ============================================================ */
18
+
19
+ :root {
20
+ /* ===== Base Colors ===== */
21
+ --accent-base: #0f6cbd;
22
+ --neutral-base: #808080;
23
+
24
+ /* ===== Trim Endpoints (fast-colors ColorPalette) ===== */
25
+ /*
26
+ * trimLight = position 0.185 from white→base, segPos = 0.185/0.5 = 0.37
27
+ * trimDark = position 0.84 from base→black, segPos = (0.84-0.5)/0.5 = 0.68
28
+ */
29
+ --neutral-trim-light: color-mix(in srgb, var(--neutral-base) 37%, white 63%);
30
+ --neutral-trim-dark: color-mix(in srgb, black 68%, var(--neutral-base) 32%);
31
+
32
+ --brand-trim-light: color-mix(in srgb, var(--accent-base) 37%, white 63%);
33
+ --brand-trim-dark: color-mix(in srgb, black 68%, var(--accent-base) 32%);
34
+
35
+ /* ===== Neutral Palette (16 stops) ===== */
36
+ /*
37
+ * Scale direction: trimDark(0) → baseColor(0.5) → trimLight(1)
38
+ * Mapping: N=10(darkest) … N=100(base) … N=160(lightest)
39
+ * Dark side: segPos = (100 - N) / 90
40
+ * Light side: segPos = (N - 100) / 60
41
+ */
42
+ --neutral-10: var(--neutral-trim-dark);
43
+ --neutral-20: color-mix(in srgb, var(--neutral-trim-dark) 88.9%, var(--neutral-base) 11.1%);
44
+ --neutral-30: color-mix(in srgb, var(--neutral-trim-dark) 77.8%, var(--neutral-base) 22.2%);
45
+ --neutral-40: color-mix(in srgb, var(--neutral-trim-dark) 66.7%, var(--neutral-base) 33.3%);
46
+ --neutral-50: color-mix(in srgb, var(--neutral-trim-dark) 55.6%, var(--neutral-base) 44.4%);
47
+ --neutral-60: color-mix(in srgb, var(--neutral-trim-dark) 44.4%, var(--neutral-base) 55.6%);
48
+ --neutral-70: color-mix(in srgb, var(--neutral-trim-dark) 33.3%, var(--neutral-base) 66.7%);
49
+ --neutral-80: color-mix(in srgb, var(--neutral-trim-dark) 22.2%, var(--neutral-base) 77.8%);
50
+ --neutral-90: color-mix(in srgb, var(--neutral-trim-dark) 11.1%, var(--neutral-base) 88.9%);
51
+ --neutral-100: var(--neutral-base);
52
+ --neutral-110: color-mix(in srgb, var(--neutral-trim-light) 16.7%, var(--neutral-base) 83.3%);
53
+ --neutral-120: color-mix(in srgb, var(--neutral-trim-light) 33.3%, var(--neutral-base) 66.7%);
54
+ --neutral-130: color-mix(in srgb, var(--neutral-trim-light) 50%, var(--neutral-base) 50%);
55
+ --neutral-140: color-mix(in srgb, var(--neutral-trim-light) 66.7%, var(--neutral-base) 33.3%);
56
+ --neutral-150: color-mix(in srgb, var(--neutral-trim-light) 83.3%, var(--neutral-base) 16.7%);
57
+ --neutral-160: var(--neutral-trim-light);
58
+
59
+ /* ===== Brand Palette (16 stops) ===== */
60
+ /*
61
+ * Same algorithm as neutral. Saturation adjustments from fast-colors
62
+ * (saturationLight=0.35, saturationDark=1.25, overlayDark=0.25)
63
+ * are omitted — they require LCH/LAB color space not available in CSS.
64
+ * The result is a perceptually uniform ramp through the accent color.
65
+ */
66
+ --brand-10: var(--brand-trim-dark);
67
+ --brand-20: color-mix(in srgb, var(--brand-trim-dark) 88.9%, var(--accent-base) 11.1%);
68
+ --brand-30: color-mix(in srgb, var(--brand-trim-dark) 77.8%, var(--accent-base) 22.2%);
69
+ --brand-40: color-mix(in srgb, var(--brand-trim-dark) 66.7%, var(--accent-base) 33.3%);
70
+ --brand-50: color-mix(in srgb, var(--brand-trim-dark) 55.6%, var(--accent-base) 44.4%);
71
+ --brand-60: color-mix(in srgb, var(--brand-trim-dark) 44.4%, var(--accent-base) 55.6%);
72
+ --brand-70: color-mix(in srgb, var(--brand-trim-dark) 33.3%, var(--accent-base) 66.7%);
73
+ --brand-80: color-mix(in srgb, var(--brand-trim-dark) 22.2%, var(--accent-base) 77.8%);
74
+ --brand-90: color-mix(in srgb, var(--brand-trim-dark) 11.1%, var(--accent-base) 88.9%);
75
+ --brand-100: var(--accent-base);
76
+ --brand-110: color-mix(in srgb, var(--brand-trim-light) 16.7%, var(--accent-base) 83.3%);
77
+ --brand-120: color-mix(in srgb, var(--brand-trim-light) 33.3%, var(--accent-base) 66.7%);
78
+ --brand-130: color-mix(in srgb, var(--brand-trim-light) 50%, var(--accent-base) 50%);
79
+ --brand-140: color-mix(in srgb, var(--brand-trim-light) 66.7%, var(--accent-base) 33.3%);
80
+ --brand-150: color-mix(in srgb, var(--brand-trim-light) 83.3%, var(--accent-base) 16.7%);
81
+ --brand-160: var(--brand-trim-light);
82
+
83
+ /* ===== Neutral Extensions (near-white / near-black) ===== */
84
+ /*
85
+ * The 16-stop palette clips at trimLight (~#d0d0d0) and trimDark (~#292929).
86
+ * Backgrounds, foregrounds, and inverted surfaces need values reaching
87
+ * pure white and near-black, matching official Fluent UI grey[4]..grey[98].
88
+ *
89
+ * --neutral-tint-N = mix(base N%, white) → near-white to grey[84]≈tint-32
90
+ * --neutral-shade-N = mix(black (100-N)%, base N%) → near-black to grey[44]≈shade-56
91
+ *
92
+ * In light mode (base=#808080=128): channel = 128 * shade% / 100
93
+ * In dark mode (base=#b0b0b0=176): channel = 176 * shade% / 100
94
+ *
95
+ * Official grey scale mapping (light mode, approx):
96
+ * grey[14]=#242424 → shade-28 grey[26]=#424242 → shade-52
97
+ * grey[38]=#616161 → not in shade range
98
+ *
99
+ * Official grey scale mapping (dark mode, approx):
100
+ * grey[4]=#0a0a0a → shade-6 grey[16]=#292929 → shade-23
101
+ * grey[24]=#3d3d3d → shade-35 grey[36]=#5c5c5c → shade-52
102
+ *
103
+ * Tint mapping (light mode):
104
+ * grey[98]=#fafafa → tint-4 grey[96]=#f5f5f5 → tint-8
105
+ * grey[94]=#f0f0f0 → tint-12 grey[92]=#ebebeb → tint-16
106
+ * grey[90]=#e6e6e6 → tint-20 grey[88]=#e0e0e0 → tint-24
107
+ * grey[86]=#dbdbdb → tint-28 grey[84]=#d6d6d6 → tint-32
108
+ */
109
+ --neutral-tint-4: color-mix(in srgb, var(--neutral-base) 4%, white 96%);
110
+ --neutral-tint-8: color-mix(in srgb, var(--neutral-base) 8%, white 92%);
111
+ --neutral-tint-12: color-mix(in srgb, var(--neutral-base) 12%, white 88%);
112
+ --neutral-tint-16: color-mix(in srgb, var(--neutral-base) 16%, white 84%);
113
+ --neutral-tint-20: color-mix(in srgb, var(--neutral-base) 20%, white 80%);
114
+ --neutral-tint-24: color-mix(in srgb, var(--neutral-base) 24%, white 76%);
115
+ --neutral-tint-28: color-mix(in srgb, var(--neutral-base) 28%, white 72%);
116
+ --neutral-tint-32: color-mix(in srgb, var(--neutral-base) 32%, white 68%);
117
+
118
+ --neutral-shade-2: color-mix(in srgb, black 98%, var(--neutral-base) 2%);
119
+ --neutral-shade-4: color-mix(in srgb, black 96%, var(--neutral-base) 4%);
120
+ --neutral-shade-6: color-mix(in srgb, black 94%, var(--neutral-base) 6%);
121
+ --neutral-shade-8: color-mix(in srgb, black 92%, var(--neutral-base) 8%);
122
+ --neutral-shade-10: color-mix(in srgb, black 90%, var(--neutral-base) 10%);
123
+ --neutral-shade-12: color-mix(in srgb, black 88%, var(--neutral-base) 12%);
124
+ --neutral-shade-14: color-mix(in srgb, black 86%, var(--neutral-base) 14%);
125
+ --neutral-shade-16: color-mix(in srgb, black 84%, var(--neutral-base) 16%);
126
+ --neutral-shade-18: color-mix(in srgb, black 82%, var(--neutral-base) 18%);
127
+ --neutral-shade-20: color-mix(in srgb, black 80%, var(--neutral-base) 20%);
128
+ --neutral-shade-22: color-mix(in srgb, black 78%, var(--neutral-base) 22%);
129
+ --neutral-shade-24: color-mix(in srgb, black 76%, var(--neutral-base) 24%);
130
+ --neutral-shade-26: color-mix(in srgb, black 74%, var(--neutral-base) 26%);
131
+ --neutral-shade-28: color-mix(in srgb, black 72%, var(--neutral-base) 28%);
132
+ --neutral-shade-30: color-mix(in srgb, black 70%, var(--neutral-base) 30%);
133
+ --neutral-shade-32: color-mix(in srgb, black 68%, var(--neutral-base) 32%);
134
+ --neutral-shade-34: color-mix(in srgb, black 66%, var(--neutral-base) 34%);
135
+ --neutral-shade-36: color-mix(in srgb, black 64%, var(--neutral-base) 36%);
136
+ --neutral-shade-38: color-mix(in srgb, black 62%, var(--neutral-base) 38%);
137
+ --neutral-shade-40: color-mix(in srgb, black 60%, var(--neutral-base) 40%);
138
+ --neutral-shade-42: color-mix(in srgb, black 58%, var(--neutral-base) 42%);
139
+ --neutral-shade-44: color-mix(in srgb, black 56%, var(--neutral-base) 44%);
140
+ --neutral-shade-46: color-mix(in srgb, black 54%, var(--neutral-base) 46%);
141
+ --neutral-shade-48: color-mix(in srgb, black 52%, var(--neutral-base) 48%);
142
+ --neutral-shade-50: color-mix(in srgb, black 50%, var(--neutral-base) 50%);
143
+ --neutral-shade-52: color-mix(in srgb, black 48%, var(--neutral-base) 52%);
144
+ --neutral-shade-54: color-mix(in srgb, black 46%, var(--neutral-base) 54%);
145
+ --neutral-shade-56: color-mix(in srgb, black 44%, var(--neutral-base) 56%);
146
+
147
+ /* ===== Brand Color Tokens ===== */
148
+ /*
149
+ * Mapped to match official Fluent UI v9 brandWeb ramp indices.
150
+ * brand-10 = darkest, brand-100 = base (accent), brand-160 = lightest
151
+ * @see fluentui/packages/tokens/src/global/brandColors.ts
152
+ */
153
+ --colorBrandBackground: var(--brand-80);
154
+ --colorBrandBackgroundHover: var(--brand-70);
155
+ --colorBrandBackgroundPressed: var(--brand-40);
156
+ --colorBrandBackgroundSelected: var(--brand-60);
157
+ --colorBrandBackground2: var(--brand-160);
158
+ --colorBrandBackground2Hover: var(--brand-150);
159
+ --colorBrandBackground2Pressed: var(--brand-130);
160
+ --colorBrandBackgroundStatic: var(--brand-80);
161
+ --colorBrandBackgroundInverted: #fff;
162
+ --colorBrandBackgroundInvertedHover: var(--brand-150);
163
+ --colorBrandBackgroundInvertedPressed: var(--brand-140);
164
+ --colorBrandBackgroundInvertedSelected: var(--brand-150);
165
+ --colorBrandBackgroundDisabled: var(--neutral-150);
166
+
167
+ /* ===== Brand Foreground Tokens ===== */
168
+ --colorBrandForeground1: var(--brand-80);
169
+ --colorBrandForeground2: var(--brand-110);
170
+ --colorBrandForegroundLink: var(--brand-70);
171
+ --colorBrandForegroundLinkHover: var(--brand-60);
172
+ --colorBrandForegroundLinkPressed: var(--brand-40);
173
+ --colorBrandForegroundLinkSelected: var(--brand-70);
174
+ --colorBrandForegroundInverted: var(--brand-100);
175
+ --colorBrandForegroundInvertedHover: var(--brand-110);
176
+ --colorBrandForegroundInvertedPressed: var(--brand-100);
177
+ --colorBrandForegroundOnLight: var(--brand-80);
178
+
179
+ /* ===== Brand Stroke Tokens ===== */
180
+ --colorBrandStroke1: var(--brand-80);
181
+ --colorBrandStroke2: var(--brand-140);
182
+
183
+ /* ===== Compound Brand Tokens ===== */
184
+ --colorCompoundBrandBackground: var(--brand-80);
185
+ --colorCompoundBrandBackgroundHover: var(--brand-70);
186
+ --colorCompoundBrandBackgroundPressed: var(--brand-60);
187
+ --colorCompoundBrandStroke: var(--brand-80);
188
+ --colorCompoundBrandStrokeHover: var(--brand-70);
189
+ --colorCompoundBrandStrokePressed: var(--brand-60);
190
+ --colorCompoundBrandForeground1: var(--brand-80);
191
+ --colorCompoundBrandForeground1Hover: var(--brand-70);
192
+ --colorCompoundBrandForeground1Pressed: var(--brand-60);
193
+
194
+ /* ===== Neutral Foreground Tokens ===== */
195
+ /*
196
+ * Dark end of the palette: trimDark→baseColor gives darker-than-base values.
197
+ * neutral-10 ≈ grey[16] | neutral-40 ≈ grey[28] | neutral-70 ≈ grey[40]
198
+ * Official: Fg1=grey[14], Fg2=grey[26], Fg3=grey[38], Fg4=grey[44]
199
+ * Hover/Pressed/Selected get DARKER (lower neutral index = more towards trimDark).
200
+ * Disabled gets LIGHTER (neutral-150 on the light side, ≈ grey[76]).
201
+ */
202
+ --colorNeutralForeground1: var(--neutral-10);
203
+ --colorNeutralForeground1Hover: var(--neutral-10);
204
+ --colorNeutralForeground1Pressed: var(--neutral-10);
205
+ --colorNeutralForeground1Selected: var(--neutral-10);
206
+ --colorNeutralForeground2: var(--neutral-40);
207
+ --colorNeutralForeground2Hover: var(--neutral-10);
208
+ --colorNeutralForeground2Pressed: var(--neutral-10);
209
+ --colorNeutralForeground2Selected: var(--neutral-10);
210
+ --colorNeutralForeground2BrandHover: var(--brand-60);
211
+ --colorNeutralForeground2BrandPressed: var(--brand-40);
212
+ --colorNeutralForeground2BrandSelected: var(--brand-50);
213
+ --colorNeutralForeground3: var(--neutral-70);
214
+ --colorNeutralForeground3Hover: var(--neutral-40);
215
+ --colorNeutralForeground3Pressed: var(--neutral-40);
216
+ --colorNeutralForeground3Selected: var(--neutral-40);
217
+ --colorNeutralForeground3BrandHover: var(--brand-60);
218
+ --colorNeutralForeground3BrandPressed: var(--brand-40);
219
+ --colorNeutralForeground3BrandSelected: var(--brand-50);
220
+ --colorNeutralForeground4: var(--neutral-80);
221
+ --colorNeutralForegroundDisabled: var(--neutral-150);
222
+ --colorNeutralForegroundInverted: white;
223
+ --colorNeutralForegroundInvertedHover: white;
224
+ --colorNeutralForegroundInvertedPressed: white;
225
+ --colorNeutralForegroundInvertedSelected: white;
226
+ --colorNeutralForegroundInverted2: white;
227
+ --colorNeutralForegroundOnBrand: #fff;
228
+ --colorNeutralForegroundInvertedLink: white;
229
+ --colorNeutralForegroundInvertedLinkHover: white;
230
+ --colorNeutralForegroundInvertedLinkPressed: white;
231
+ --colorNeutralForegroundInvertedLinkSelected: white;
232
+ --colorNeutralForegroundInvertedDisabled: white;
233
+
234
+ /*
235
+ * Backgrounds: near-white through grey[90], matching official Fluent UI.
236
+ * Uses --neutral-tint-N which derives from --neutral-base, so they auto-adapt
237
+ * when the base changes per theme.
238
+ *
239
+ * Official grey mapping: tint-4≈grey[98], tint-8≈grey[96], tint-12≈grey[94],
240
+ * tint-16≈grey[92], tint-20≈grey[90], tint-24≈grey[88], tint-28≈grey[86],
241
+ * tint-32≈grey[84]
242
+ *
243
+ * Background4-6 get LIGHTER on hover/press in the official Fluent UI
244
+ * (these are darker surfaces like card headers — interaction reveals them).
245
+ */
246
+ --colorNeutralBackground1: white;
247
+ --colorNeutralBackground1Hover: var(--neutral-tint-8);
248
+ --colorNeutralBackground1Pressed: var(--neutral-tint-24);
249
+ --colorNeutralBackground1Selected: var(--neutral-tint-16);
250
+ --colorNeutralBackground2: var(--neutral-tint-4);
251
+ --colorNeutralBackground2Hover: var(--neutral-tint-12);
252
+ --colorNeutralBackground2Pressed: var(--neutral-tint-28);
253
+ --colorNeutralBackground2Selected: var(--neutral-tint-20);
254
+ --colorNeutralBackground3: var(--neutral-tint-8);
255
+ --colorNeutralBackground3Hover: var(--neutral-tint-16);
256
+ --colorNeutralBackground3Pressed: var(--neutral-tint-32);
257
+ --colorNeutralBackground3Selected: var(--neutral-tint-24);
258
+ --colorNeutralBackground4: var(--neutral-tint-12);
259
+ --colorNeutralBackground4Hover: var(--neutral-tint-4);
260
+ --colorNeutralBackground4Pressed: var(--neutral-tint-8);
261
+ --colorNeutralBackground4Selected: white;
262
+ --colorNeutralBackground5: var(--neutral-tint-16);
263
+ --colorNeutralBackground5Hover: var(--neutral-tint-8);
264
+ --colorNeutralBackground5Pressed: var(--neutral-tint-12);
265
+ --colorNeutralBackground5Selected: var(--neutral-tint-4);
266
+ --colorNeutralBackground6: var(--neutral-tint-20);
267
+ --colorNeutralBackground6Hover: var(--neutral-tint-12);
268
+ --colorNeutralBackground6Pressed: var(--neutral-tint-24);
269
+ --colorNeutralBackground6Selected: var(--neutral-tint-16);
270
+ --colorNeutralBackgroundDisabled: var(--neutral-tint-12);
271
+ --colorNeutralBackgroundInverted: var(--neutral-10);
272
+ --colorNeutralBackgroundInvertedHover: var(--neutral-20);
273
+ --colorNeutralBackgroundInvertedPressed: var(--neutral-shade-24);
274
+ --colorNeutralBackgroundInvertedSelected: var(--neutral-shade-44);
275
+
276
+ /* ===== Neutral Stroke Tokens ===== */
277
+ /*
278
+ * Official: Stroke1=grey[82](#d1d1d1), Stroke2=grey[88](#e0e0e0),
279
+ * Stroke3=grey[94](#f0f0f0), StrokeAccessible=grey[38](#616161).
280
+ * Stroke1 ≈ trimLight(neutral-160), Stroke2+3 are beyond trim → use tints.
281
+ * StrokeAccessible uses a dark-side palette stop for contrast on white.
282
+ */
283
+ --colorNeutralStroke1: var(--neutral-160);
284
+ --colorNeutralStroke1Hover: var(--neutral-150);
285
+ --colorNeutralStroke1Pressed: var(--neutral-140);
286
+ --colorNeutralStroke1Selected: var(--neutral-150);
287
+ --colorNeutralStroke2: var(--neutral-tint-24);
288
+ --colorNeutralStroke2Hover: var(--neutral-tint-20);
289
+ --colorNeutralStroke2Pressed: var(--neutral-tint-16);
290
+ --colorNeutralStroke2Selected: var(--neutral-tint-20);
291
+ --colorNeutralStroke3: var(--neutral-tint-12);
292
+ --colorNeutralStroke3Hover: var(--neutral-tint-8);
293
+ --colorNeutralStroke3Pressed: var(--neutral-tint-4);
294
+ --colorNeutralStroke3Selected: var(--neutral-tint-8);
295
+ --colorNeutralStrokeAccessible: var(--neutral-70);
296
+ --colorNeutralStrokeAccessibleHover: var(--neutral-60);
297
+ --colorNeutralStrokeAccessiblePressed: var(--neutral-50);
298
+ --colorNeutralStrokeAccessibleSelected: var(--brand-80);
299
+ --colorNeutralStrokeDisabled: var(--neutral-tint-24);
300
+ --colorNeutralStrokeInverted: var(--neutral-160);
301
+ --colorNeutralStrokeInvertedHover: var(--neutral-160);
302
+ --colorNeutralStrokeInvertedPressed: var(--neutral-160);
303
+ --colorNeutralStrokeInvertedSelected: var(--neutral-160);
304
+
305
+ /* ===== Stroke Focus ===== */
306
+ --colorStrokeFocus1: white;
307
+ --colorStrokeFocus2: #000;
308
+
309
+ /* ===== Transparent Tokens ===== */
310
+ --colorTransparentBackground: transparent;
311
+ --colorTransparentBackgroundHover: var(--neutral-tint-8);
312
+ --colorTransparentBackgroundPressed: var(--neutral-tint-16);
313
+ --colorTransparentBackgroundSelected: var(--neutral-tint-16);
314
+ --colorTransparentStroke: transparent;
315
+ --colorTransparentStrokeInteractive: transparent;
316
+ --colorTransparentStrokeDisabled: transparent;
317
+
318
+ /* ===== Subtle Tokens ===== */
319
+ /*
320
+ * Official light: SubtleBackground=transparent; we use a faint tint for visibility.
321
+ * SubtleBackgroundInverted uses dark-side palette stops (near ~grey[16-24]).
322
+ */
323
+ --colorSubtleBackground: var(--neutral-tint-8);
324
+ --colorSubtleBackgroundHover: var(--neutral-tint-16);
325
+ --colorSubtleBackgroundPressed: var(--neutral-tint-24);
326
+ --colorSubtleBackgroundSelected: var(--neutral-tint-24);
327
+ --colorSubtleBackgroundInverted: var(--neutral-shade-32);
328
+ --colorSubtleBackgroundInvertedHover: var(--neutral-shade-48);
329
+ --colorSubtleBackgroundInvertedPressed: var(--neutral-shade-28);
330
+ --colorSubtleBackgroundInvertedSelected: var(--neutral-shade-44);
331
+
332
+ /* ===== Scrollbar ===== */
333
+ /*
334
+ * Official light: blackAlpha[50]=rgba(0,0,0,0.5) → translucent overlay.
335
+ * The overlay approach requires rgba which can't derive from --neutral-base.
336
+ */
337
+ --colorScrollbarOverlay: rgba(0,0,0,0.5);
338
+
339
+ /* ===== Static Neutral Tokens ===== */
340
+ --colorNeutralForeground1Static: #242424;
341
+ --colorNeutralForegroundStaticInverted: #ffffff;
342
+
343
+ /* ===== Status Tokens ===== */
344
+ --colorPaletteRedBackground1: #fdf6f6;
345
+ --colorPaletteRedBackground2: #f1bbbc;
346
+ --colorPaletteRedBackground3: #d13438;
347
+ --colorPaletteRedForeground1: #bc2f32;
348
+ --colorPaletteRedForeground2: #751d1f;
349
+ --colorPaletteRedForeground3: #e37d80;
350
+ --colorPaletteRedBorder1: #f1bbbc;
351
+ --colorPaletteRedBorder2: #d13438;
352
+ --colorPaletteRedBorderActive: #d13438;
353
+ --colorStatusDangerBackground1: var(--colorPaletteRedBackground1);
354
+ --colorStatusDangerForeground1: var(--colorPaletteRedForeground1);
355
+ --colorStatusDangerForeground3: var(--colorPaletteRedForeground1);
356
+ --colorStatusDangerBorderActive: var(--colorPaletteRedBorderActive);
357
+ --colorStatusDangerBorderHover: var(--colorPaletteRedBorderActive);
358
+
359
+ --colorPaletteGreenBackground1: #f1faf1;
360
+ --colorPaletteGreenBackground2: #9fd89f;
361
+ --colorPaletteGreenBackground3: #107c10;
362
+ --colorPaletteGreenForeground1: #0e700e;
363
+ --colorPaletteGreenForeground2: #094509;
364
+ --colorPaletteGreenForeground3: #9fd89f;
365
+ --colorPaletteGreenBorder1: #9fd89f;
366
+ --colorPaletteGreenBorder2: #107c10;
367
+ --colorStatusSuccessBackground1: var(--colorPaletteGreenBackground1);
368
+ --colorStatusSuccessForeground1: var(--colorPaletteGreenForeground1);
369
+ --colorStatusSuccessForeground3: var(--colorPaletteGreenForeground1);
370
+
371
+ --colorPaletteDarkOrangeBackground1: #fdf6f3;
372
+ --colorPaletteDarkOrangeBackground2: #f4bfab;
373
+ --colorPaletteDarkOrangeBackground3: #da3b01;
374
+ --colorPaletteDarkOrangeForeground1: #c43501;
375
+ --colorPaletteDarkOrangeForeground2: #7a2101;
376
+ --colorPaletteDarkOrangeForeground3: #e9835e;
377
+ --colorPaletteDarkOrangeBorder1: #f4bfab;
378
+ --colorPaletteDarkOrangeBorder2: #da3b01;
379
+ --colorPaletteDarkOrangeBorderActive: #da3b01;
380
+ --colorStatusWarningBackground1: var(--colorPaletteDarkOrangeBackground1);
381
+ --colorStatusWarningForeground1: var(--colorPaletteDarkOrangeForeground1);
382
+ --colorStatusWarningForeground3: var(--colorPaletteDarkOrangeForeground1);
383
+ --colorStatusWarningBorderActive: var(--colorPaletteDarkOrangeBorderActive);
384
+ --colorStatusWarningBorderHover: var(--colorPaletteDarkOrangeBorderActive);
385
+
386
+ --colorPaletteYellowBackground1: #fffef5;
387
+ --colorPaletteYellowBackground2: #fef7b2;
388
+ --colorPaletteYellowBackground3: #fde300;
389
+ --colorPaletteYellowForeground1: #817400;
390
+ --colorPaletteYellowForeground2: #c0ad00;
391
+ --colorPaletteYellowForeground3: #fde300;
392
+ --colorPaletteYellowBorder1: #fef7b2;
393
+ --colorPaletteYellowBorder2: #fde300;
394
+ --colorStatusWarningBackground2: var(--colorPaletteYellowBackground1);
395
+ --colorStatusWarningForeground2: var(--colorPaletteYellowForeground1);
396
+
397
+ --colorPaletteBerryForeground1: var(--brand-70);
398
+ --colorPaletteBerryBackground1: var(--brand-140);
399
+ --colorPaletteBerryBackground2: var(--brand-80);
400
+ --colorPaletteBerryForeground2: var(--brand-70);
401
+ --colorPaletteBerryForeground3: var(--brand-70);
402
+ --colorPaletteBerryBorder1: var(--brand-130);
403
+ --colorPaletteBerryBorder2: var(--brand-80);
404
+
405
+ --colorPaletteLightGreenForeground1: #0e700e;
406
+ --colorPaletteLightGreenBackground1: #a1e3a1;
407
+ --colorPaletteLightGreenBackground2: #0e700e;
408
+ --colorPaletteLightGreenForeground2: #0e700e;
409
+ --colorPaletteLightGreenBorder1: #b4dbb4;
410
+ --colorPaletteLightGreenBorder2: #0e700e;
411
+
412
+ --colorPaletteMarigoldForeground1: #da3b01;
413
+ --colorPaletteMarigoldBackground1: #fad3c5;
414
+ --colorPaletteMarigoldBackground2: #da3b01;
415
+ --colorPaletteMarigoldForeground2: #da3b01;
416
+ --colorPaletteMarigoldForeground3: #da3b01;
417
+ --colorPaletteMarigoldBorderActive: #da3b01;
418
+ --colorPaletteMarigoldBorder1: #eab8a5;
419
+ --colorPaletteMarigoldBorder2: #da3b01;
420
+
421
+ /* ===== Shadow Color Tokens ===== */
422
+ --colorNeutralShadowAmbient: rgba(0,0,0,0.12);
423
+ --colorNeutralShadowKey: rgba(0,0,0,0.14);
424
+ --colorBrandShadowAmbient: rgba(0,0,0,0.30);
425
+ --colorBrandShadowKey: rgba(0,0,0,0.25);
426
+
427
+ /* ===== Shadows ===== */
428
+ --shadow2: 0 0 2px var(--colorNeutralShadowAmbient), 0 1px 2px var(--colorNeutralShadowKey);
429
+ --shadow4: 0 0 2px var(--colorNeutralShadowAmbient), 0 2px 4px var(--colorNeutralShadowKey);
430
+ --shadow8: 0 0 2px var(--colorNeutralShadowAmbient), 0 4px 8px var(--colorNeutralShadowKey);
431
+ --shadow16: 0 0 2px var(--colorNeutralShadowAmbient), 0 8px 16px var(--colorNeutralShadowKey);
432
+ --shadow28: 0 0 8px var(--colorNeutralShadowAmbient), 0 14px 28px var(--colorNeutralShadowKey);
433
+ --shadow64: 0 0 8px var(--colorNeutralShadowAmbient), 0 32px 64px var(--colorNeutralShadowKey);
434
+ --shadow2Brand: 0 0 2px var(--colorBrandShadowAmbient), 0 1px 2px var(--colorBrandShadowKey);
435
+ --shadow4Brand: 0 0 2px var(--colorBrandShadowAmbient), 0 2px 4px var(--colorBrandShadowKey);
436
+ --shadow8Brand: 0 0 2px var(--colorBrandShadowAmbient), 0 4px 8px var(--colorBrandShadowKey);
437
+ --shadow16Brand: 0 0 2px var(--colorBrandShadowAmbient), 0 8px 16px var(--colorBrandShadowKey);
438
+ --shadow28Brand: 0 0 8px var(--colorBrandShadowAmbient), 0 14px 28px var(--colorBrandShadowKey);
439
+ --shadow64Brand: 0 0 8px var(--colorBrandShadowAmbient), 0 32px 64px var(--colorBrandShadowKey);
440
+
441
+ /* ===== Stroke Widths ===== */
442
+ --strokeWidthNone: 0;
443
+ --strokeWidthThin: 1px;
444
+ --strokeWidthThick: 2px;
445
+ --strokeWidthThicker: 3px;
446
+ --strokeWidthThickest: 4px;
447
+
448
+ /* ===== Border Radii ===== */
449
+ --borderRadiusNone: 0;
450
+ --borderRadiusSmall: 2px;
451
+ --borderRadiusMedium: 4px;
452
+ --borderRadiusLarge: 6px;
453
+ --borderRadiusXLarge: 8px;
454
+ --borderRadiusCircular: 9999px;
455
+
456
+ /* ===== Spacing (8px grid) ===== */
457
+ --spacingHorizontalNone: 0;
458
+ --spacingHorizontalXXS: 2px;
459
+ --spacingHorizontalXS: 4px;
460
+ --spacingHorizontalSNudge: 6px;
461
+ --spacingHorizontalS: 8px;
462
+ --spacingHorizontalMNudge: 10px;
463
+ --spacingHorizontalM: 12px;
464
+ --spacingHorizontalL: 16px;
465
+ --spacingHorizontalXL: 20px;
466
+ --spacingHorizontalXXL: 24px;
467
+ --spacingHorizontalXXXL: 32px;
468
+ --spacingVerticalNone: 0;
469
+ --spacingVerticalXXS: 2px;
470
+ --spacingVerticalXS: 4px;
471
+ --spacingVerticalSNudge: 6px;
472
+ --spacingVerticalS: 8px;
473
+ --spacingVerticalMNudge: 10px;
474
+ --spacingVerticalM: 12px;
475
+ --spacingVerticalL: 16px;
476
+ --spacingVerticalXL: 20px;
477
+ --spacingVerticalXXL: 24px;
478
+ --spacingVerticalXXXL: 32px;
479
+
480
+ /* ===== Typography ===== */
481
+ --fontSizeBase100: 10px;
482
+ --fontSizeBase200: 12px;
483
+ --fontSizeBase300: 14px;
484
+ --fontSizeBase400: 16px;
485
+ --fontSizeBase500: 20px;
486
+ --fontSizeBase600: 24px;
487
+ --fontSizeBase700: 28px;
488
+ --fontSizeBase800: 32px;
489
+ --fontSizeBase900: 40px;
490
+ --fontSizeBase1000: 68px;
491
+
492
+ --lineHeightBase100: 14px;
493
+ --lineHeightBase200: 16px;
494
+ --lineHeightBase300: 20px;
495
+ --lineHeightBase400: 22px;
496
+ --lineHeightBase500: 28px;
497
+ --lineHeightBase600: 32px;
498
+ --lineHeightBase700: 36px;
499
+ --lineHeightBase800: 40px;
500
+ --lineHeightBase900: 52px;
501
+ --lineHeightBase1000: 92px;
502
+
503
+ --fontFamilyBase: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
504
+ --fontFamilyMonospace: 'Cascadia Code', 'Fira Code', Consolas, 'Courier New', monospace;
505
+ --fontFamilyNumeric: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
506
+
507
+ --fontWeightRegular: 400;
508
+ --fontWeightMedium: 500;
509
+ --fontWeightSemibold: 600;
510
+ --fontWeightBold: 700;
511
+
512
+ /* ===== Duration ===== */
513
+ --durationUltraFast: 50ms;
514
+ --durationFaster: 100ms;
515
+ --durationFast: 150ms;
516
+ --durationNormal: 200ms;
517
+ --durationGentle: 250ms;
518
+ --durationSlow: 300ms;
519
+ --durationSlower: 400ms;
520
+ --durationUltraSlow: 500ms;
521
+
522
+ /* ===== Curves ===== */
523
+ --curveAccelerateMax: cubic-bezier(1, 0, 1, 1);
524
+ --curveAccelerateMid: cubic-bezier(0.7, 0, 1, 0.5);
525
+ --curveAccelerateMin: cubic-bezier(0.8, 0, 1, 1);
526
+ --curveDecelerateMax: cubic-bezier(0, 0, 0, 1);
527
+ --curveDecelerateMid: cubic-bezier(0.1, 0.9, 0.2, 1);
528
+ --curveDecelerateMin: cubic-bezier(0.33, 0, 0.1, 1);
529
+ --curveEasyEaseMax: cubic-bezier(0.8, 0, 0.2, 1);
530
+ --curveEasyEase: cubic-bezier(0.33, 0, 0.67, 1);
531
+ --curveLinear: cubic-bezier(0, 0, 1, 1);
532
+
533
+ /* ===== Unstyled host default ===== */
534
+ --colorNeutralForegroundOnBrand: #fff;
535
+ }
536
+
537
+ /* ===== Dark Theme Override ===== */
538
+ /*
539
+ * Dark mode uses clipLight=0 so trimLight = pure white.
540
+ * This ensures foreground text reaches maximum contrast (#ffffff)
541
+ * matching the official Fluent UI darkColor token values.
542
+ *
543
+ * Tint/Shade auto-adapt: with base=#b0b0b0:
544
+ * shade-24 = mix(black 76%, #b0b0b0 24%) ≈ grey[16]
545
+ * shade-36 = mix(black 64%, #b0b0b0 36%) ≈ grey[24]
546
+ * tint-24 = mix(#b0b0b0 24%, white 76%) ≈ grey[90]
547
+ *
548
+ * Official reference: fluentui/packages/tokens/src/alias/darkColor.ts
549
+ */
550
+ :root.dark,
551
+ body.dark {
552
+ --accent-base: #479ef5;
553
+ --neutral-base: #b0b0b0;
554
+
555
+ /* clipLight=0 → trimLight = white (pure foreground for dark theme) */
556
+ --neutral-trim-light: white;
557
+ --neutral-trim-dark: color-mix(in srgb, black 68%, var(--neutral-base) 32%);
558
+ --brand-trim-light: white;
559
+ --brand-trim-dark: color-mix(in srgb, black 68%, var(--accent-base) 32%);
560
+
561
+ /* ===== Foregrounds ===== */
562
+ /*
563
+ * Official order: Fg1=white(neutral-160), Fg2=~grey[84](neutral-130),
564
+ * Fg3=~grey[68](neutral-90), Fg4=~grey[60](neutral-80).
565
+ * Disabled = ~grey[36](neutral-40), very dark against near-black backgrounds.
566
+ */
567
+ --colorNeutralForeground1: var(--neutral-160);
568
+ --colorNeutralForeground1Hover: var(--neutral-150);
569
+ --colorNeutralForeground1Pressed: var(--neutral-150);
570
+ --colorNeutralForeground1Selected: var(--neutral-150);
571
+ --colorNeutralForeground2: var(--neutral-130);
572
+ --colorNeutralForeground2Hover: var(--neutral-140);
573
+ --colorNeutralForeground2Pressed: var(--neutral-150);
574
+ --colorNeutralForeground2Selected: var(--neutral-140);
575
+ --colorNeutralForeground2BrandHover: var(--brand-100);
576
+ --colorNeutralForeground2BrandPressed: var(--brand-110);
577
+ --colorNeutralForeground2BrandSelected: var(--brand-100);
578
+ --colorNeutralForeground3: var(--neutral-90);
579
+ --colorNeutralForeground3Hover: var(--neutral-100);
580
+ --colorNeutralForeground3Pressed: var(--neutral-110);
581
+ --colorNeutralForeground3Selected: var(--neutral-100);
582
+ --colorNeutralForeground3BrandHover: var(--brand-100);
583
+ --colorNeutralForeground3BrandPressed: var(--brand-110);
584
+ --colorNeutralForeground3BrandSelected: var(--brand-100);
585
+ --colorNeutralForeground4: var(--neutral-80);
586
+ --colorNeutralForegroundDisabled: var(--neutral-40);
587
+
588
+ /* ForegroundInverted: dark grey (#242424=~grey[14]) against white inverted surface */
589
+ --colorNeutralForegroundInverted: var(--neutral-shade-22);
590
+ --colorNeutralForegroundInvertedHover: var(--neutral-shade-22);
591
+ --colorNeutralForegroundInvertedPressed: var(--neutral-shade-22);
592
+ --colorNeutralForegroundInvertedSelected: var(--neutral-shade-22);
593
+ --colorNeutralForegroundInverted2: var(--neutral-shade-22);
594
+ --colorNeutralForegroundInvertedLink: var(--neutral-shade-22);
595
+ --colorNeutralForegroundInvertedLinkHover: var(--neutral-shade-22);
596
+ --colorNeutralForegroundInvertedLinkPressed: var(--neutral-shade-22);
597
+ --colorNeutralForegroundInvertedLinkSelected: var(--neutral-shade-22);
598
+ --colorNeutralForegroundInvertedDisabled: var(--neutral-shade-44);
599
+
600
+ /* ===== Backgrounds ===== */
601
+ /*
602
+ * Near-black using --neutral-shade-N.
603
+ * Official: Bg1=grey[16], Bg2=grey[12], Bg3=grey[8], Bg4=grey[4],
604
+ * Bg5=black, Bg6=grey[20].
605
+ */
606
+ --colorNeutralBackground1: var(--neutral-shade-24);
607
+ --colorNeutralBackground1Hover: var(--neutral-shade-36);
608
+ --colorNeutralBackground1Pressed: var(--neutral-shade-18);
609
+ --colorNeutralBackground1Selected: var(--neutral-shade-32);
610
+ --colorNeutralBackground2: var(--neutral-shade-18);
611
+ --colorNeutralBackground2Hover: var(--neutral-shade-30);
612
+ --colorNeutralBackground2Pressed: var(--neutral-shade-12);
613
+ --colorNeutralBackground2Selected: var(--neutral-shade-26);
614
+ --colorNeutralBackground3: var(--neutral-shade-12);
615
+ --colorNeutralBackground3Hover: var(--neutral-shade-24);
616
+ --colorNeutralBackground3Pressed: var(--neutral-shade-6);
617
+ --colorNeutralBackground3Selected: var(--neutral-shade-20);
618
+ --colorNeutralBackground4: var(--neutral-shade-6);
619
+ --colorNeutralBackground4Hover: var(--neutral-shade-18);
620
+ --colorNeutralBackground4Pressed: black;
621
+ --colorNeutralBackground4Selected: var(--neutral-shade-16);
622
+ --colorNeutralBackground5: black;
623
+ --colorNeutralBackground5Hover: var(--neutral-shade-12);
624
+ --colorNeutralBackground5Pressed: var(--neutral-shade-4);
625
+ --colorNeutralBackground5Selected: var(--neutral-shade-8);
626
+ --colorNeutralBackground6: var(--neutral-shade-30);
627
+ --colorNeutralBackground6Hover: var(--neutral-shade-36);
628
+ --colorNeutralBackground6Pressed: var(--neutral-shade-42);
629
+ --colorNeutralBackground6Selected: var(--neutral-shade-38);
630
+ --colorNeutralBackgroundDisabled: var(--neutral-shade-12);
631
+
632
+ --colorNeutralBackgroundInverted: white;
633
+ --colorNeutralBackgroundInvertedHover: var(--neutral-tint-8);
634
+ --colorNeutralBackgroundInvertedPressed: var(--neutral-tint-16);
635
+ --colorNeutralBackgroundInvertedSelected: var(--neutral-tint-8);
636
+
637
+ /* ===== Strokes ===== */
638
+ /*
639
+ * Official dark: Stroke1=grey[40](neutral-70), Stroke2=grey[32](neutral-60),
640
+ * Stroke3=grey[24](neutral-shade-36), StrokeAccessible=grey[68](neutral-100).
641
+ */
642
+ --colorNeutralStroke1: var(--neutral-70);
643
+ --colorNeutralStroke1Hover: var(--neutral-60);
644
+ --colorNeutralStroke1Pressed: var(--neutral-50);
645
+ --colorNeutralStroke1Selected: var(--neutral-60);
646
+ --colorNeutralStroke2: var(--neutral-50);
647
+ --colorNeutralStroke2Hover: var(--neutral-60);
648
+ --colorNeutralStroke2Pressed: var(--neutral-70);
649
+ --colorNeutralStroke2Selected: var(--neutral-60);
650
+ --colorNeutralStroke3: var(--neutral-shade-36);
651
+ --colorNeutralStroke3Hover: var(--neutral-40);
652
+ --colorNeutralStroke3Pressed: var(--neutral-50);
653
+ --colorNeutralStroke3Selected: var(--neutral-40);
654
+ --colorNeutralStrokeAccessible: var(--neutral-100);
655
+ --colorNeutralStrokeAccessibleHover: var(--neutral-110);
656
+ --colorNeutralStrokeAccessiblePressed: var(--neutral-120);
657
+ --colorNeutralStrokeAccessibleSelected: var(--brand-100);
658
+ --colorNeutralStrokeDisabled: var(--neutral-40);
659
+ --colorNeutralStrokeInverted: var(--neutral-160);
660
+ --colorNeutralStrokeInvertedHover: var(--neutral-160);
661
+ --colorNeutralStrokeInvertedPressed: var(--neutral-160);
662
+ --colorNeutralStrokeInvertedSelected: var(--neutral-160);
663
+
664
+ /* ===== Brand Stroke (dark mode) ===== */
665
+ --colorBrandStroke1: var(--brand-100);
666
+ --colorBrandStroke2: var(--brand-50);
667
+
668
+ /* ===== Brand Foreground (dark mode) ===== */
669
+ --colorBrandForeground1: var(--brand-90);
670
+ --colorBrandForegroundLink: var(--brand-100);
671
+ --colorBrandForegroundLinkHover: var(--brand-110);
672
+ --colorBrandForegroundLinkPressed: var(--brand-90);
673
+ --colorBrandForegroundLinkSelected: var(--brand-100);
674
+
675
+ /* ===== Transparent ===== */
676
+ --colorTransparentBackgroundHover: var(--neutral-shade-36);
677
+ --colorTransparentBackgroundPressed: var(--neutral-shade-24);
678
+ --colorTransparentBackgroundSelected: var(--neutral-shade-24);
679
+
680
+ /* ===== Subtle ===== */
681
+ --colorSubtleBackground: var(--neutral-shade-36);
682
+ --colorSubtleBackgroundHover: var(--neutral-shade-24);
683
+ --colorSubtleBackgroundPressed: var(--neutral-shade-18);
684
+ --colorSubtleBackgroundSelected: var(--neutral-shade-30);
685
+ --colorSubtleBackgroundInverted: var(--neutral-tint-8);
686
+ --colorSubtleBackgroundInvertedHover: var(--neutral-tint-16);
687
+ --colorSubtleBackgroundInvertedPressed: var(--neutral-tint-24);
688
+ --colorSubtleBackgroundInvertedSelected: var(--neutral-tint-16);
689
+
690
+ /* ===== Focus ===== */
691
+ --colorStrokeFocus1: black;
692
+ --colorStrokeFocus2: white;
693
+
694
+ /* ===== Scrollbar ===== */
695
+ --colorScrollbarOverlay: rgba(255,255,255,0.6);
696
+
697
+ /* ===== Shadow Color Tokens (dark) ===== */
698
+ --colorNeutralShadowAmbient: rgba(0,0,0,0.24);
699
+ --colorNeutralShadowKey: rgba(0,0,0,0.28);
700
+ --colorBrandShadowAmbient: rgba(0,0,0,0.30);
701
+ --colorBrandShadowKey: rgba(0,0,0,0.25);
702
+ }
703
+
704
+ /* ===== Forced Colors (High Contrast) ===== */
705
+ @media (forced-colors: active) {
706
+ :root {
707
+ --colorNeutralForeground1: ButtonText;
708
+ --colorNeutralBackground1: ButtonFace;
709
+ }
710
+ }
711
+
712
+ /* ===== Reduced Motion ===== */
713
+ @media (prefers-reduced-motion: reduce) {
714
+ :root {
715
+ --durationUltraFast: 0.01ms;
716
+ --durationFaster: 0.01ms;
717
+ --durationFast: 0.01ms;
718
+ --durationNormal: 0.01ms;
719
+ --durationGentle: 0.01ms;
720
+ --durationSlow: 0.01ms;
721
+ --durationSlower: 0.01ms;
722
+ --durationUltraSlow: 0.01ms;
723
+ }
724
+ }