@halogen-ui/tokens 0.1.0

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.
package/dist/theme.css ADDED
@@ -0,0 +1,859 @@
1
+ /**
2
+ * Halogen Tailwind v4 theme — GENERATED. Do not edit.
3
+ * Source: packages/tokens/src/ · Rebuild: pnpm --filter @halogen-ui/tokens build
4
+ *
5
+ * Import AFTER tokens.css:
6
+ * @import '@halogen-ui/tokens/tokens.css';
7
+ * @import '@halogen-ui/tokens/theme.css';
8
+ */
9
+
10
+ /**
11
+ * @theme inline — not plain @theme.
12
+ *
13
+ * Plain @theme creates an indirection: Tailwind declares
14
+ * --color-line-focus: var(--halogen-line-focus) on :root and utilities
15
+ * reference ar(--color-line-focus). Through Tailwind's Vite plugin those
16
+ * theme variables are never emitted, so every utility resolves to an empty
17
+ * custom property and silently falls back to an inherited value — a button with
18
+ * the wrong text color and an invisible focus ring, with no error anywhere.
19
+ *
20
+ * inline substitutes the value into the utility instead:
21
+ * outline-color: var(--halogen-line-focus). One variable, resolved at use
22
+ * site, which is also what makes per-theme switching work — the theme swaps
23
+ * --halogen-* and every utility follows.
24
+ */
25
+ @theme inline {
26
+ /* Reset every namespace Halogen owns. This is the enforcement mechanism:
27
+ an off-token utility does not fail review, it fails to compile. */
28
+ --color-*: initial;
29
+ --spacing-*: initial;
30
+ --radius-*: initial;
31
+ --font-*: initial;
32
+ --text-*: initial;
33
+ --font-weight-*: initial;
34
+ --tracking-*: initial;
35
+ --leading-*: initial;
36
+ --shadow-*: initial;
37
+ --ease-*: initial;
38
+ --breakpoint-*: initial;
39
+ --container-*: initial;
40
+ --transition-duration-*: initial;
41
+ --aspect-*: initial;
42
+ --z-index-*: initial;
43
+
44
+ /* Abolished: reset with nothing declared back, so these cannot compile at all.
45
+ The aesthetic direction rejects blur/glassmorphism and keyframe animation;
46
+ this makes that a compiler error rather than a review comment. */
47
+ --blur-*: initial;
48
+
49
+ /* Bounded: reset, then reopened to an explicit whitelist and nothing more. */
50
+ --animate-*: initial;
51
+ --animate-spin: halogen-spin var(--halogen-duration-spin) linear infinite;
52
+ /* The second entry in this namespace, and argued for like the first: a
53
+ skeleton is a loading indicator, and a placeholder that never moves reads
54
+ as broken layout rather than as pending content. Still not a license for
55
+ animate-bounce. */
56
+ --animate-pulse: halogen-pulse var(--halogen-duration-pulse) var(--halogen-easing-move) infinite;
57
+
58
+ /* ---- Semantic colors. These are what components use. ----
59
+ Gradients are deliberately absent: a gradient is a background-IMAGE, and
60
+ putting one in the color namespace produces
61
+ background-color: linear-gradient(...), which is invalid CSS. The
62
+ declaration is dropped, the utility compiles, and nothing renders. Every
63
+ Halogen gradient was dead from Phase 1 until this was found. */
64
+ --color-surface-ground: var(--halogen-surface-ground);
65
+ --color-surface-raised: var(--halogen-surface-raised);
66
+ --color-surface-overlay: var(--halogen-surface-overlay);
67
+ --color-surface-floating: var(--halogen-surface-floating);
68
+ --color-surface-modal: var(--halogen-surface-modal);
69
+ --color-surface-subtle: var(--halogen-surface-subtle);
70
+ --color-surface-field: var(--halogen-surface-field);
71
+ --color-surface-subtle-hover: var(--halogen-surface-subtle-hover);
72
+ --color-surface-subtle-active: var(--halogen-surface-subtle-active);
73
+ --color-surface-state-hover: var(--halogen-surface-state-hover);
74
+ --color-surface-state-active: var(--halogen-surface-state-active);
75
+ --color-surface-selection: var(--halogen-surface-selection);
76
+ --color-surface-knob: var(--halogen-surface-knob);
77
+ --color-surface-inverse: var(--halogen-surface-inverse);
78
+ --color-surface-accent: var(--halogen-surface-accent);
79
+ --color-surface-accent-hover: var(--halogen-surface-accent-hover);
80
+ --color-surface-accent-active: var(--halogen-surface-accent-active);
81
+ --color-surface-accent-subtle: var(--halogen-surface-accent-subtle);
82
+ --color-surface-accent-subtle-hover: var(--halogen-surface-accent-subtle-hover);
83
+ --color-surface-disabled: var(--halogen-surface-disabled);
84
+ --color-surface-scrim: var(--halogen-surface-scrim);
85
+ --color-ink-primary: var(--halogen-ink-primary);
86
+ --color-ink-secondary: var(--halogen-ink-secondary);
87
+ --color-ink-tertiary: var(--halogen-ink-tertiary);
88
+ --color-ink-placeholder: var(--halogen-ink-placeholder);
89
+ --color-ink-disabled: var(--halogen-ink-disabled);
90
+ --color-ink-accent: var(--halogen-ink-accent);
91
+ --color-ink-on-accent-subtle: var(--halogen-ink-on-accent-subtle);
92
+ --color-ink-on-accent: var(--halogen-ink-on-accent);
93
+ --color-ink-on-gradient: var(--halogen-ink-on-gradient);
94
+ --color-ink-on-scrim: var(--halogen-ink-on-scrim);
95
+ --color-ink-on-scrim-secondary: var(--halogen-ink-on-scrim-secondary);
96
+ --color-ink-inverse: var(--halogen-ink-inverse);
97
+ --color-ink-link: var(--halogen-ink-link);
98
+ --color-ink-link-hover: var(--halogen-ink-link-hover);
99
+ --color-line-subtle: var(--halogen-line-subtle);
100
+ --color-line-divider: var(--halogen-line-divider);
101
+ --color-line-control: var(--halogen-line-control);
102
+ --color-line-strong: var(--halogen-line-strong);
103
+ --color-line-focus: var(--halogen-line-focus);
104
+ --color-line-focus-glow: var(--halogen-line-focus-glow);
105
+ --color-line-accent: var(--halogen-line-accent);
106
+ --color-line-disabled: var(--halogen-line-disabled);
107
+ --color-line-edge-highlight: var(--halogen-line-edge-highlight);
108
+ --color-status-success-solid: var(--halogen-status-success-solid);
109
+ --color-status-success-on-solid: var(--halogen-status-success-on-solid);
110
+ --color-status-success-ink: var(--halogen-status-success-ink);
111
+ --color-status-success-surface: var(--halogen-status-success-surface);
112
+ --color-status-success-line: var(--halogen-status-success-line);
113
+ --color-status-warning-solid: var(--halogen-status-warning-solid);
114
+ --color-status-warning-on-solid: var(--halogen-status-warning-on-solid);
115
+ --color-status-warning-ink: var(--halogen-status-warning-ink);
116
+ --color-status-warning-surface: var(--halogen-status-warning-surface);
117
+ --color-status-warning-line: var(--halogen-status-warning-line);
118
+ --color-status-error-solid: var(--halogen-status-error-solid);
119
+ --color-status-error-on-solid: var(--halogen-status-error-on-solid);
120
+ --color-status-error-ink: var(--halogen-status-error-ink);
121
+ --color-status-error-surface: var(--halogen-status-error-surface);
122
+ --color-status-error-line: var(--halogen-status-error-line);
123
+ --color-status-info-solid: var(--halogen-status-info-solid);
124
+ --color-status-info-on-solid: var(--halogen-status-info-on-solid);
125
+ --color-status-info-ink: var(--halogen-status-info-ink);
126
+ --color-status-info-surface: var(--halogen-status-info-surface);
127
+ --color-status-info-line: var(--halogen-status-info-line);
128
+ --color-viz-1: var(--halogen-viz-1);
129
+ --color-viz-2: var(--halogen-viz-2);
130
+ --color-viz-3: var(--halogen-viz-3);
131
+ --color-viz-4: var(--halogen-viz-4);
132
+ --color-viz-5: var(--halogen-viz-5);
133
+ --color-viz-6: var(--halogen-viz-6);
134
+ --color-viz-7: var(--halogen-viz-7);
135
+ --color-viz-grid: var(--halogen-viz-grid);
136
+ --color-viz-axis: var(--halogen-viz-axis);
137
+ --color-viz-sequential-0: var(--halogen-viz-sequential-0);
138
+ --color-viz-sequential-1: var(--halogen-viz-sequential-1);
139
+ --color-viz-sequential-2: var(--halogen-viz-sequential-2);
140
+ --color-viz-sequential-3: var(--halogen-viz-sequential-3);
141
+ --color-viz-sequential-4: var(--halogen-viz-sequential-4);
142
+ --color-viz-diverging-neg-2: var(--halogen-viz-diverging-neg-2);
143
+ --color-viz-diverging-neg-1: var(--halogen-viz-diverging-neg-1);
144
+ --color-viz-diverging-0: var(--halogen-viz-diverging-0);
145
+ --color-viz-diverging-pos-1: var(--halogen-viz-diverging-pos-1);
146
+ --color-viz-diverging-pos-2: var(--halogen-viz-diverging-pos-2);
147
+ --color-elevation-1: var(--halogen-elevation-1);
148
+ --color-elevation-2: var(--halogen-elevation-2);
149
+ --color-elevation-3: var(--halogen-elevation-3);
150
+ --color-elevation-4: var(--halogen-elevation-4);
151
+
152
+ /* ---- Primitive escape hatch. Marketing surfaces only; never product UI. ---- */
153
+ --color-neutral-0: var(--halogen-color-neutral-0);
154
+ --color-neutral-25: var(--halogen-color-neutral-25);
155
+ --color-neutral-50: var(--halogen-color-neutral-50);
156
+ --color-neutral-100: var(--halogen-color-neutral-100);
157
+ --color-neutral-200: var(--halogen-color-neutral-200);
158
+ --color-neutral-300: var(--halogen-color-neutral-300);
159
+ --color-neutral-400: var(--halogen-color-neutral-400);
160
+ --color-neutral-450: var(--halogen-color-neutral-450);
161
+ --color-neutral-500: var(--halogen-color-neutral-500);
162
+ --color-neutral-550: var(--halogen-color-neutral-550);
163
+ --color-neutral-600: var(--halogen-color-neutral-600);
164
+ --color-neutral-700: var(--halogen-color-neutral-700);
165
+ --color-neutral-800: var(--halogen-color-neutral-800);
166
+ --color-neutral-850: var(--halogen-color-neutral-850);
167
+ --color-neutral-900: var(--halogen-color-neutral-900);
168
+ --color-neutral-950: var(--halogen-color-neutral-950);
169
+ --color-neutral-1000: var(--halogen-color-neutral-1000);
170
+ --color-state-hover-dark: var(--halogen-color-state-hover-dark);
171
+ --color-state-active-dark: var(--halogen-color-state-active-dark);
172
+ --color-state-hover-light: var(--halogen-color-state-hover-light);
173
+ --color-state-active-light: var(--halogen-color-state-active-light);
174
+ --color-state-focus-glow: var(--halogen-color-state-focus-glow);
175
+ --color-state-selection-dark: var(--halogen-color-state-selection-dark);
176
+ --color-state-selection-light: var(--halogen-color-state-selection-light);
177
+ --color-heat-dark-0: var(--halogen-color-heat-dark-0);
178
+ --color-heat-dark-1: var(--halogen-color-heat-dark-1);
179
+ --color-heat-dark-2: var(--halogen-color-heat-dark-2);
180
+ --color-heat-dark-3: var(--halogen-color-heat-dark-3);
181
+ --color-heat-dark-4: var(--halogen-color-heat-dark-4);
182
+ --color-heat-light-0: var(--halogen-color-heat-light-0);
183
+ --color-heat-light-1: var(--halogen-color-heat-light-1);
184
+ --color-heat-light-2: var(--halogen-color-heat-light-2);
185
+ --color-heat-light-3: var(--halogen-color-heat-light-3);
186
+ --color-heat-light-4: var(--halogen-color-heat-light-4);
187
+ --color-orange-base: var(--halogen-color-orange-base);
188
+ --color-orange-bright: var(--halogen-color-orange-bright);
189
+ --color-orange-dim: var(--halogen-color-orange-dim);
190
+ --color-orange-text-light: var(--halogen-color-orange-text-light);
191
+ --color-orange-mark-light: var(--halogen-color-orange-mark-light);
192
+ --color-orange-surface-dark: var(--halogen-color-orange-surface-dark);
193
+ --color-orange-surface-light: var(--halogen-color-orange-surface-light);
194
+ --color-orange-surface-dark-hover: var(--halogen-color-orange-surface-dark-hover);
195
+ --color-orange-surface-light-hover: var(--halogen-color-orange-surface-light-hover);
196
+ --color-orange-border-dark: var(--halogen-color-orange-border-dark);
197
+ --color-orange-border-light: var(--halogen-color-orange-border-light);
198
+ --color-orange-text-light-strong: var(--halogen-color-orange-text-light-strong);
199
+ --color-orange-text-on-chip-light: var(--halogen-color-orange-text-on-chip-light);
200
+ --color-coral-base: var(--halogen-color-coral-base);
201
+ --color-coral-bright: var(--halogen-color-coral-bright);
202
+ --color-coral-dim: var(--halogen-color-coral-dim);
203
+ --color-coral-text-light: var(--halogen-color-coral-text-light);
204
+ --color-coral-mark-light: var(--halogen-color-coral-mark-light);
205
+ --color-amber-base: var(--halogen-color-amber-base);
206
+ --color-amber-bright: var(--halogen-color-amber-bright);
207
+ --color-amber-dim: var(--halogen-color-amber-dim);
208
+ --color-amber-text-light: var(--halogen-color-amber-text-light);
209
+ --color-amber-mark-light: var(--halogen-color-amber-mark-light);
210
+ --color-yellow-base: var(--halogen-color-yellow-base);
211
+ --color-yellow-bright: var(--halogen-color-yellow-bright);
212
+ --color-yellow-dim: var(--halogen-color-yellow-dim);
213
+ --color-yellow-text-light: var(--halogen-color-yellow-text-light);
214
+ --color-yellow-mark-light: var(--halogen-color-yellow-mark-light);
215
+ --color-peach-base: var(--halogen-color-peach-base);
216
+ --color-peach-bright: var(--halogen-color-peach-bright);
217
+ --color-peach-dim: var(--halogen-color-peach-dim);
218
+ --color-peach-text-light: var(--halogen-color-peach-text-light);
219
+ --color-peach-mark-light: var(--halogen-color-peach-mark-light);
220
+ --color-pink-base: var(--halogen-color-pink-base);
221
+ --color-pink-bright: var(--halogen-color-pink-bright);
222
+ --color-pink-dim: var(--halogen-color-pink-dim);
223
+ --color-pink-text-light: var(--halogen-color-pink-text-light);
224
+ --color-pink-mark-light: var(--halogen-color-pink-mark-light);
225
+ --color-teal-base: var(--halogen-color-teal-base);
226
+ --color-teal-bright: var(--halogen-color-teal-bright);
227
+ --color-teal-dim: var(--halogen-color-teal-dim);
228
+ --color-teal-text-light: var(--halogen-color-teal-text-light);
229
+ --color-teal-mark-light: var(--halogen-color-teal-mark-light);
230
+ --color-teal-surface-dark: var(--halogen-color-teal-surface-dark);
231
+ --color-teal-surface-light: var(--halogen-color-teal-surface-light);
232
+ --color-teal-surface-dark-hover: var(--halogen-color-teal-surface-dark-hover);
233
+ --color-teal-surface-light-hover: var(--halogen-color-teal-surface-light-hover);
234
+ --color-teal-border-dark: var(--halogen-color-teal-border-dark);
235
+ --color-teal-border-light: var(--halogen-color-teal-border-light);
236
+ --color-teal-text-light-strong: var(--halogen-color-teal-text-light-strong);
237
+ --color-teal-text-on-chip-light: var(--halogen-color-teal-text-on-chip-light);
238
+ --color-success-solid: var(--halogen-color-success-solid);
239
+ --color-success-on-solid: var(--halogen-color-success-on-solid);
240
+ --color-success-surface-dark: var(--halogen-color-success-surface-dark);
241
+ --color-success-surface-light: var(--halogen-color-success-surface-light);
242
+ --color-success-text-dark: var(--halogen-color-success-text-dark);
243
+ --color-success-text-light: var(--halogen-color-success-text-light);
244
+ --color-success-border-dark: var(--halogen-color-success-border-dark);
245
+ --color-success-border-light: var(--halogen-color-success-border-light);
246
+ --color-warning-solid: var(--halogen-color-warning-solid);
247
+ --color-warning-on-solid: var(--halogen-color-warning-on-solid);
248
+ --color-warning-surface-dark: var(--halogen-color-warning-surface-dark);
249
+ --color-warning-surface-light: var(--halogen-color-warning-surface-light);
250
+ --color-warning-text-dark: var(--halogen-color-warning-text-dark);
251
+ --color-warning-text-light: var(--halogen-color-warning-text-light);
252
+ --color-warning-border-dark: var(--halogen-color-warning-border-dark);
253
+ --color-warning-border-light: var(--halogen-color-warning-border-light);
254
+ --color-error-solid: var(--halogen-color-error-solid);
255
+ --color-error-on-solid: var(--halogen-color-error-on-solid);
256
+ --color-error-surface-dark: var(--halogen-color-error-surface-dark);
257
+ --color-error-surface-light: var(--halogen-color-error-surface-light);
258
+ --color-error-text-dark: var(--halogen-color-error-text-dark);
259
+ --color-error-text-light: var(--halogen-color-error-text-light);
260
+ --color-error-border-dark: var(--halogen-color-error-border-dark);
261
+ --color-error-border-light: var(--halogen-color-error-border-light);
262
+
263
+ /* ---- Spacing ---- */
264
+ --spacing-0: var(--halogen-space-0);
265
+ --spacing-1: var(--halogen-space-1);
266
+ --spacing-2: var(--halogen-space-2);
267
+ --spacing-3: var(--halogen-space-3);
268
+ --spacing-4: var(--halogen-space-4);
269
+ --spacing-5: var(--halogen-space-5);
270
+ --spacing-6: var(--halogen-space-6);
271
+ --spacing-8: var(--halogen-space-8);
272
+ --spacing-10: var(--halogen-space-10);
273
+ --spacing-12: var(--halogen-space-12);
274
+ --spacing-16: var(--halogen-space-16);
275
+ --spacing-20: var(--halogen-space-20);
276
+ --spacing-24: var(--halogen-space-24);
277
+ --spacing-32: var(--halogen-space-32);
278
+ --spacing-40: var(--halogen-space-40);
279
+ --spacing-48: var(--halogen-space-48);
280
+ --spacing-64: var(--halogen-space-64);
281
+ --spacing-80: var(--halogen-space-80);
282
+ --spacing-px: var(--halogen-space-px);
283
+ --spacing-half: var(--halogen-space-half);
284
+ --spacing-target-min: var(--halogen-target-min);
285
+ --spacing-target-touch: var(--halogen-target-touch);
286
+ --spacing-control-sm: var(--halogen-control-sm);
287
+ --spacing-control-md: var(--halogen-control-md);
288
+ --spacing-control-lg: var(--halogen-control-lg);
289
+ --spacing-control-xl: var(--halogen-control-xl);
290
+ --spacing-icon-sm: var(--halogen-icon-sm);
291
+ --spacing-icon-md: var(--halogen-icon-md);
292
+ --spacing-icon-lg: var(--halogen-icon-lg);
293
+
294
+ /* ---- Radius ---- */
295
+ --radius-none: var(--halogen-radius-none);
296
+ --radius-xs: var(--halogen-radius-xs);
297
+ --radius-sm: var(--halogen-radius-sm);
298
+ --radius-md: var(--halogen-radius-md);
299
+ --radius-lg: var(--halogen-radius-lg);
300
+ --radius-xl: var(--halogen-radius-xl);
301
+ --radius-2xl: var(--halogen-radius-2xl);
302
+ --radius-full: var(--halogen-radius-full);
303
+
304
+ /* ---- Type ---- */
305
+ --font-sans: var(--halogen-font-family-sans);
306
+ --font-mono: var(--halogen-font-family-mono);
307
+ --text-2xs: var(--halogen-font-size-2xs);
308
+ --text-2xs--line-height: 16px;
309
+ --text-2xs--letter-spacing: 0.015em;
310
+ --text-xs: var(--halogen-font-size-xs);
311
+ --text-xs--line-height: 16px;
312
+ --text-xs--letter-spacing: 0.005em;
313
+ --text-sm: var(--halogen-font-size-sm);
314
+ --text-sm--line-height: 20px;
315
+ --text-sm--letter-spacing: 0.01em;
316
+ --text-base: var(--halogen-font-size-base);
317
+ --text-base--line-height: 20px;
318
+ --text-base--letter-spacing: 0em;
319
+ --text-md: var(--halogen-font-size-md);
320
+ --text-md--line-height: 24px;
321
+ --text-md--letter-spacing: 0em;
322
+ --text-lg: var(--halogen-font-size-lg);
323
+ --text-lg--line-height: 28px;
324
+ --text-lg--letter-spacing: -0.005em;
325
+ --text-xl: var(--halogen-font-size-xl);
326
+ --text-xl--line-height: 28px;
327
+ --text-xl--letter-spacing: -0.01em;
328
+ --text-display-xs: var(--halogen-display-size-xs);
329
+ --text-display-xs--line-height: 1.25;
330
+ --text-display-xs--letter-spacing: -0.01em;
331
+ --text-display-sm: var(--halogen-display-size-sm);
332
+ --text-display-sm--line-height: 1.2;
333
+ --text-display-sm--letter-spacing: -0.015em;
334
+ --text-display-md: var(--halogen-display-size-md);
335
+ --text-display-md--line-height: 1.1;
336
+ --text-display-md--letter-spacing: -0.02em;
337
+ --text-display-lg: var(--halogen-display-size-lg);
338
+ --text-display-lg--line-height: 1.05;
339
+ --text-display-lg--letter-spacing: -0.025em;
340
+ --text-display-xl: var(--halogen-display-size-xl);
341
+ --text-display-xl--line-height: 1;
342
+ --text-display-xl--letter-spacing: -0.03em;
343
+ --text-display-2xl: var(--halogen-display-size-2xl);
344
+ --text-display-2xl--line-height: 0.95;
345
+ --text-display-2xl--letter-spacing: -0.035em;
346
+ --font-weight-regular: var(--halogen-font-weight-regular);
347
+ --font-weight-medium: var(--halogen-font-weight-medium);
348
+ --font-weight-semibold: var(--halogen-font-weight-semibold);
349
+ --font-weight-bold: var(--halogen-font-weight-bold);
350
+ --tracking-wider: var(--halogen-tracking-wider);
351
+ --tracking-wide: var(--halogen-tracking-wide);
352
+ --tracking-normal: var(--halogen-tracking-normal);
353
+ --tracking-tight: var(--halogen-tracking-tight);
354
+ --tracking-tighter: var(--halogen-tracking-tighter);
355
+ --tracking-tightest: var(--halogen-tracking-tightest);
356
+ --tracking-display: var(--halogen-tracking-display);
357
+ --tracking-display-tight: var(--halogen-tracking-display-tight);
358
+ --leading-none: var(--halogen-line-height-none);
359
+ --leading-display-2xl: var(--halogen-line-height-display-2xl);
360
+ --leading-display-xl: var(--halogen-line-height-display-xl);
361
+ --leading-display-lg: var(--halogen-line-height-display-lg);
362
+ --leading-display-md: var(--halogen-line-height-display-md);
363
+ --leading-display-sm: var(--halogen-line-height-display-sm);
364
+ --leading-display-xs: var(--halogen-line-height-display-xs);
365
+ --leading-snug: var(--halogen-line-height-snug);
366
+ --leading-normal: var(--halogen-line-height-normal);
367
+ --leading-relaxed: var(--halogen-line-height-relaxed);
368
+
369
+ /* ---- Elevation & motion ---- */
370
+ --shadow-sm: var(--halogen-shadow-sm);
371
+ --shadow-md: var(--halogen-shadow-md);
372
+ --shadow-lg: var(--halogen-shadow-lg);
373
+ --shadow-none: var(--halogen-shadow-none);
374
+ --ease-enter: var(--halogen-easing-enter);
375
+ --ease-exit: var(--halogen-easing-exit);
376
+ --ease-move: var(--halogen-easing-move);
377
+ --ease-overshoot: var(--halogen-easing-overshoot);
378
+ --ease-linear: var(--halogen-easing-linear);
379
+ --transition-duration-instant: var(--halogen-duration-instant);
380
+ --transition-duration-press: var(--halogen-duration-press);
381
+ --transition-duration-fast: var(--halogen-duration-fast);
382
+ --transition-duration-base: var(--halogen-duration-base);
383
+ --transition-duration-slow: var(--halogen-duration-slow);
384
+ --transition-duration-slower: var(--halogen-duration-slower);
385
+ --transition-duration-deliberate: var(--halogen-duration-deliberate);
386
+
387
+ /* ---- Breakpoints ----
388
+ LITERAL values, deliberately, not var() references.
389
+ @theme inline substitutes the declared value straight into the media
390
+ query, and @media (width >= var(--x)) is invalid CSS that never matches.
391
+ Emitting a reference here silently kills every responsive utility in the
392
+ system: sm:, md:, lg: all stop applying, with no error anywhere. */
393
+ --breakpoint-sm: 640px;
394
+ --breakpoint-md: 768px;
395
+ --breakpoint-lg: 1024px;
396
+ --breakpoint-xl: 1280px;
397
+ --breakpoint-2xl: 1536px;
398
+
399
+ /* ---- Containers ---- */
400
+ --container-prose: var(--halogen-container-prose);
401
+ --container-default: var(--halogen-container-default);
402
+ --container-wide: var(--halogen-container-wide);
403
+ --container-measure: var(--halogen-measure-prose);
404
+ --container-measure-narrow: var(--halogen-measure-narrow);
405
+
406
+ /* ---- Stacking order ---- */
407
+ --z-index-base: var(--halogen-layer-base);
408
+ --z-index-raised: var(--halogen-layer-raised);
409
+ --z-index-sticky: var(--halogen-layer-sticky);
410
+ --z-index-overlay: var(--halogen-layer-overlay);
411
+ --z-index-modal: var(--halogen-layer-modal);
412
+ --z-index-popover: var(--halogen-layer-popover);
413
+ --z-index-toast: var(--halogen-layer-toast);
414
+ --z-index-tooltip: var(--halogen-layer-tooltip);
415
+ --aspect-video: var(--halogen-aspect-video);
416
+ --aspect-square: var(--halogen-aspect-square);
417
+ --aspect-wide: var(--halogen-aspect-wide);
418
+ }
419
+
420
+ /**
421
+ * The surface transition.
422
+ *
423
+ * Every Tailwind transition utility — including ransition-colors — animates
424
+ * outline-color, which means the focus ring FADES IN over the transition
425
+ * duration. A keyboard user needs immediate confirmation of where focus landed;
426
+ * a ring that eases in reads as lag, and it is the kind of thing that never
427
+ * shows up in a screenshot.
428
+ *
429
+ * So Halogen transitions the three properties a control actually needs and
430
+ * leaves the focus indicator instantaneous. Named for what it does, not for the
431
+ * property list, so components do not have to remember why.
432
+ */
433
+ @utility transition-surface {
434
+ transition-property: color, background-color, border-color, scale;
435
+ transition-timing-function: var(--halogen-easing-enter);
436
+ transition-duration: var(--halogen-duration-fast);
437
+ }
438
+
439
+ /**
440
+ * The push.
441
+ *
442
+ * Composes onto transition-surface rather than replacing it, so a control keeps
443
+ * its color transitions and gains a press. Only the :active state is declared
444
+ * here; the return journey is whatever transition-surface already set, which is
445
+ * what produces the asymmetry — 70ms down, 120ms back.
446
+ *
447
+ * Under reduced motion --press-scale resolves to 1 and this becomes inert,
448
+ * while the active background color still confirms the press.
449
+ */
450
+ /**
451
+ * Press feedback.
452
+ *
453
+ * Put this on the shape a person sees, which is not always the element that
454
+ * receives the event: a removable chip is one pill holding two buttons, and a
455
+ * press on either half must move the whole pill. That works because :active
456
+ * propagates to ancestors — measured, because the obvious alternative does not.
457
+ * :has(:active) compiles fine and never matches in Chrome, so a shell styled
458
+ * that way silently does nothing.
459
+ */
460
+ @utility press {
461
+ &:active {
462
+ scale: var(--halogen-press-scale);
463
+ transition-duration: var(--halogen-duration-press);
464
+ }
465
+ }
466
+
467
+ /**
468
+ * The icon reel. Slot-machine swap on hover.
469
+ *
470
+ * Expects exactly two children: the resting glyph and its twin. The twin sits
471
+ * one window below, absolutely positioned so it adds no height, and both travel
472
+ * together when the enclosing .group is hovered.
473
+ *
474
+ * Hover only — never focus. A keyboard user tabbing along a toolbar would
475
+ * otherwise set every icon spinning, which is motion they did not ask for and
476
+ * cannot avoid.
477
+ */
478
+ /**
479
+ * The seam between an addon and the field it belongs to.
480
+ *
481
+ * Both carry their own `px-3`, so a prefix sat **24px** from the text it
482
+ * introduces: "https://" and the URL after it read as two controls that happen
483
+ * to share a border, which is the one thing an input group exists not to be.
484
+ *
485
+ * The group owns the seam, the same way it already owns the border, the radius
486
+ * and the focus ring. The addon keeps its outer padding — that gap is against
487
+ * the border and is correct — and the field drops the padding on the side where
488
+ * an addon meets it, leaving one 12px gap instead of two.
489
+ *
490
+ * Only the leading side. A trailing addon is usually `divided`, and there the
491
+ * field's own padding is what keeps the value off the rule.
492
+ */
493
+ @utility input-seam {
494
+ & > * + input {
495
+ padding-inline-start: var(--halogen-space-0);
496
+ }
497
+ }
498
+
499
+ @utility reel {
500
+ position: relative;
501
+ display: block;
502
+ overflow: hidden;
503
+
504
+ /* ease-move, not ease-enter. The enter curve is heavily front-loaded, which
505
+ is right for something arriving but wrong for something travelling: the
506
+ glyph jumped and settled, and the roll itself was over in about 30ms —
507
+ legible only frame by frame. An in-out curve spends the duration on the
508
+ journey, which is the whole point of a reel. */
509
+ & > * {
510
+ display: block;
511
+ transition: translate var(--halogen-duration-slow) var(--halogen-easing-move);
512
+ }
513
+ & > :last-child {
514
+ position: absolute;
515
+ inset: 0;
516
+ translate: 0 var(--halogen-reel-travel);
517
+ }
518
+
519
+ .group:hover & > :first-child {
520
+ translate: 0 calc(-1 * var(--halogen-reel-travel));
521
+ }
522
+ .group:hover & > :last-child {
523
+ translate: 0 0;
524
+ }
525
+ }
526
+
527
+ /**
528
+ * A focus ring that fades in, for surfaces you settle into rather than pass
529
+ * through.
530
+ *
531
+ * Buttons keep an instantaneous ring: focus moves through a toolbar quickly and
532
+ * a keyboard user needs to know where it landed with no delay. A text field is
533
+ * the opposite — focus there is a sustained state you are about to type into,
534
+ * and a ring that eases in reads as the field waking up rather than as lag.
535
+ *
536
+ * The outline is always present and transparent, so only its color animates;
537
+ * transitioning width would make the ring jump. Under reduced motion the
538
+ * duration collapses and the ring appears instantly.
539
+ */
540
+ /* ---- Named state variants ----
541
+ Radix reports component state through data-state. Without names for those,
542
+ every component reaches for an arbitrary variant like data-[state=checked]:,
543
+ which the no-arbitrary-values rule rejects and which reads as a selector
544
+ rather than as a state. Naming them once here keeps component code legible
545
+ and the rule strict. */
546
+ @custom-variant checked (&[data-state='checked']);
547
+ @custom-variant unchecked (&[data-state='unchecked']);
548
+ /* A selected tab. Radix Tabs reports data-state="active", NOT "checked" — and
549
+ Tabs was styled with checked:, so the selected tab had a transparent underline
550
+ in the underline variant, no fill in the pill variant, and the same ink as its
551
+ neighbours. Every rule compiled; none of them ever matched, so the strip
552
+ shipped with no visible selected state at all. */
553
+ @custom-variant active (&[data-state='active']);
554
+ @custom-variant open (&[data-state='open']);
555
+ @custom-variant closed (&[data-state='closed']);
556
+ /* A checkbox's third state. Radix reports it as data-state="indeterminate",
557
+ and without a name for it every tri-state checkbox reaches for an arbitrary
558
+ variant — which is exactly the shape the rule exists to reject. */
559
+ @custom-variant indeterminate (&[data-state='indeterminate']);
560
+ /* Radix highlights the active menu/select option with data-highlighted rather
561
+ than :hover, because the highlight follows the keyboard as well as the
562
+ pointer. */
563
+ @custom-variant highlighted (&[data-highlighted]);
564
+ /* A select trigger showing its placeholder rather than a chosen value. Radix
565
+ marks it with data-placeholder, and without a name the only way to style it
566
+ is an arbitrary variant. */
567
+ @custom-variant placeholder-shown (&[data-placeholder]);
568
+ /* A toggle button's pressed state. Radix reports it as data-state="on"; a
569
+ native toggle uses aria-pressed. Both are named here so a component does not
570
+ have to know which kind it is. */
571
+ @custom-variant pressed (&[data-state='on'], &[aria-pressed='true']);
572
+ /* A group whose field inside it is invalid. The border belongs to the group, so
573
+ the group is what has to react. */
574
+ @custom-variant has-aria-invalid (&:has([aria-invalid='true']));
575
+
576
+ /* ---- Brand gradients ----
577
+ Utilities rather than theme colors, because they set background-image.
578
+ Five named blends and no ad-hoc ones: the aesthetic direction allows them on
579
+ heroes, feature surfaces, progress fills and decorative fields, and nowhere
580
+ else. no-gradient-on-controls enforces the second half of that. */
581
+ @utility gradient-ember {
582
+ background-image: var(--halogen-gradient-ember);
583
+ }
584
+
585
+ @utility gradient-solar {
586
+ background-image: var(--halogen-gradient-solar);
587
+ }
588
+
589
+ @utility gradient-dusk {
590
+ background-image: var(--halogen-gradient-dusk);
591
+ }
592
+
593
+ @utility gradient-glow {
594
+ background-image: var(--halogen-gradient-glow);
595
+ }
596
+
597
+ @utility gradient-ground {
598
+ background-image: var(--halogen-gradient-ground);
599
+ }
600
+
601
+ /**
602
+ * Floating elevation.
603
+ *
604
+ * Phase 1 specified an inset top highlight here, on the theory that a shadow is
605
+ * nearly invisible on a near-black ground so light should appear to catch the
606
+ * top edge instead. Built in Phase 3 and reversed on sight: on a panel with a
607
+ * border it reads as a stray line across the top of every dialog, not as light.
608
+ * The border and the surface change carry the elevation on their own.
609
+ */
610
+ /**
611
+ * A panel nested inside a card: elevation 2.
612
+ *
613
+ * Reads as a no-op in the dark theme and as a real shadow in the light one,
614
+ * because that is where the fill ramp has run out. A component asks for
615
+ * "elevation 2" and the theme decides how to express it.
616
+ */
617
+ @utility elevated-raised {
618
+ box-shadow: var(--halogen-elevation-2);
619
+ }
620
+
621
+ @utility elevated-floating {
622
+ box-shadow: var(--halogen-shadow-md);
623
+ }
624
+
625
+ @utility elevated-modal {
626
+ box-shadow: var(--halogen-shadow-lg);
627
+ }
628
+
629
+ /**
630
+ * The flat scrim that makes light text legal over a gradient.
631
+ *
632
+ * Flat, never blurred: a blurred scrim makes the contrast of whatever sits
633
+ * above it impossible to verify, and the aesthetic direction rejects the look.
634
+ * The opacity is a token because it is a measured accessibility figure rather
635
+ * than a taste call - see SCRIM_OPACITY.
636
+ */
637
+ @utility gradient-scrim {
638
+ background-color: color-mix(
639
+ in srgb,
640
+ var(--halogen-surface-scrim) calc(var(--halogen-scrim-opacity) * 100%),
641
+ transparent
642
+ );
643
+ }
644
+
645
+ /**
646
+ * The modal scrim. Fade only — a scrim that slides reads as a mistake.
647
+ */
648
+ @utility overlay-scrim {
649
+ /* The only backdrop-filter in Halogen, and deliberately the only one.
650
+ The blur namespace stays abolished so no component can reach for
651
+ backdrop-blur-md; a modal scrim gets exactly one blur, from a token. */
652
+ backdrop-filter: blur(var(--halogen-scrim-blur));
653
+
654
+ &[data-state='open'] {
655
+ animation: halogen-fade-in var(--halogen-duration-fade) var(--halogen-easing-enter);
656
+ }
657
+ &[data-state='closed'] {
658
+ animation: halogen-fade-out var(--halogen-duration-fade) var(--halogen-easing-exit);
659
+ }
660
+ }
661
+
662
+ /**
663
+ * A centered panel: dialogs. Fades and settles in from fractionally small.
664
+ * Exit is faster than entry, per the system enter/exit rule.
665
+ */
666
+ @utility overlay-panel {
667
+ &[data-state='open'] {
668
+ animation:
669
+ halogen-fade-in var(--halogen-duration-fade) var(--halogen-easing-enter),
670
+ halogen-zoom-in var(--halogen-duration-base) var(--halogen-easing-enter);
671
+ }
672
+ &[data-state='closed'] {
673
+ animation:
674
+ halogen-fade-out var(--halogen-duration-fade) var(--halogen-easing-exit),
675
+ halogen-zoom-out var(--halogen-duration-fast) var(--halogen-easing-exit);
676
+ }
677
+ }
678
+
679
+ /**
680
+ * An anchored surface: popover, tooltip, menu.
681
+ *
682
+ * Enters from the direction of its trigger, which Radix reports as data-side.
683
+ * A popover placed below its trigger starts slightly above and travels down, so
684
+ * it reads as emerging from the thing that opened it rather than arriving from
685
+ * nowhere.
686
+ */
687
+ @utility overlay-pop {
688
+ --halogen-overlay-x: 0px;
689
+ --halogen-overlay-y: 0px;
690
+
691
+ &[data-side='top'] { --halogen-overlay-y: var(--halogen-travel-ui); }
692
+ &[data-side='bottom'] { --halogen-overlay-y: calc(-1 * var(--halogen-travel-ui)); }
693
+ &[data-side='left'] { --halogen-overlay-x: var(--halogen-travel-ui); }
694
+ &[data-side='right'] { --halogen-overlay-x: calc(-1 * var(--halogen-travel-ui)); }
695
+
696
+ &[data-state='open'],
697
+ &[data-state='delayed-open'] {
698
+ animation:
699
+ halogen-fade-in var(--halogen-duration-fade) var(--halogen-easing-enter),
700
+ halogen-slide-in var(--halogen-duration-fast) var(--halogen-easing-enter);
701
+ }
702
+ &[data-state='closed'] {
703
+ animation:
704
+ halogen-fade-out var(--halogen-duration-fade) var(--halogen-easing-exit),
705
+ halogen-slide-out var(--halogen-duration-fast) var(--halogen-easing-exit);
706
+ }
707
+ }
708
+
709
+ /**
710
+ * An edge panel: the sheet. Travels its own full width or height, so the
711
+ * distance is a percentage rather than the 8px product-UI travel budget — the
712
+ * panel IS the movement, not a nudge on top of one.
713
+ */
714
+ @utility overlay-sheet {
715
+ &[data-side='right'] { --halogen-overlay-x: var(--halogen-overlay-sheet-travel); }
716
+ &[data-side='left'] { --halogen-overlay-x: calc(-1 * var(--halogen-overlay-sheet-travel)); }
717
+ &[data-side='top'] { --halogen-overlay-y: calc(-1 * var(--halogen-overlay-sheet-travel)); }
718
+ &[data-side='bottom'] { --halogen-overlay-y: var(--halogen-overlay-sheet-travel); }
719
+
720
+ &[data-state='open'] {
721
+ animation:
722
+ halogen-fade-in var(--halogen-duration-fade) var(--halogen-easing-enter),
723
+ halogen-slide-in var(--halogen-duration-base) var(--halogen-easing-enter);
724
+ }
725
+ &[data-state='closed'] {
726
+ animation:
727
+ halogen-fade-out var(--halogen-duration-fade) var(--halogen-easing-exit),
728
+ halogen-slide-out var(--halogen-duration-fast) var(--halogen-easing-exit);
729
+ }
730
+ }
731
+
732
+ /**
733
+ * The toast viewport. Sets the direction its toasts travel from.
734
+ *
735
+ * Declared here rather than on the toast because the vars inherit, and the
736
+ * viewport is the thing that knows which corner it is pinned to. Corner
737
+ * positions slide horizontally — a diagonal entrance reads as a glitch.
738
+ */
739
+ @utility toast-viewport {
740
+ &[data-position='top-left'],
741
+ &[data-position='bottom-left'] {
742
+ --halogen-overlay-x: calc(-1 * var(--halogen-travel-expressive));
743
+ --halogen-overlay-y: 0px;
744
+ }
745
+ &[data-position='top-right'],
746
+ &[data-position='bottom-right'] {
747
+ --halogen-overlay-x: var(--halogen-travel-expressive);
748
+ --halogen-overlay-y: 0px;
749
+ }
750
+ &[data-position='top-center'] {
751
+ --halogen-overlay-x: 0px;
752
+ --halogen-overlay-y: calc(-1 * var(--halogen-travel-expressive));
753
+ }
754
+ &[data-position='bottom-center'] {
755
+ --halogen-overlay-x: 0px;
756
+ --halogen-overlay-y: var(--halogen-travel-expressive);
757
+ }
758
+ }
759
+
760
+ /**
761
+ * A toast.
762
+ *
763
+ * Its own motion rather than overlay-pop, because a toast that dismisses itself
764
+ * needs a leave you can actually watch. The exit runs on ease-move at
765
+ * duration-slow: an auto-dismiss that vanishes on the exit curve reads as a
766
+ * glitch, since nobody was looking at the moment it decided to go.
767
+ *
768
+ * Deliberately does not reset the travel vars — they are inherited from the
769
+ * viewport, which knows which corner it sits in.
770
+ */
771
+ @utility overlay-toast {
772
+ &[data-state='open'] {
773
+ animation:
774
+ halogen-fade-in var(--halogen-duration-fade) var(--halogen-easing-enter),
775
+ halogen-slide-in var(--halogen-duration-base) var(--halogen-easing-enter);
776
+ }
777
+ &[data-state='closed'] {
778
+ animation:
779
+ halogen-fade-out var(--halogen-duration-slow) var(--halogen-easing-move),
780
+ halogen-slide-out var(--halogen-duration-slow) var(--halogen-easing-move);
781
+ }
782
+ /* A deliberate swipe should leave immediately — the person is watching. */
783
+ &[data-swipe='end'] {
784
+ animation:
785
+ halogen-fade-out var(--halogen-duration-fast) var(--halogen-easing-exit),
786
+ halogen-slide-out var(--halogen-duration-fast) var(--halogen-easing-exit);
787
+ }
788
+ }
789
+
790
+ /**
791
+ * Accordion panel motion.
792
+ *
793
+ * Height is the one exception to the transform-and-opacity rule, and it is
794
+ * unavoidable: an accordion has to animate to its content's height, which is
795
+ * not knowable in advance. Radix measures it and hands it over as a variable,
796
+ * which is what makes this possible at all.
797
+ */
798
+ @utility accordion-panel {
799
+ overflow: hidden;
800
+
801
+ &[data-state='open'] {
802
+ animation: halogen-accordion-open var(--halogen-duration-base) var(--halogen-easing-move);
803
+ }
804
+ &[data-state='closed'] {
805
+ animation: halogen-accordion-close var(--halogen-duration-fast) var(--halogen-easing-move);
806
+ }
807
+ }
808
+
809
+ /**
810
+ * A fill that reveals rather than resizes.
811
+ *
812
+ * Progress is the one place a gradient is allowed outside a brand surface, and
813
+ * the point is that the fill travels UP the warm ramp as it advances. Scaling
814
+ * the fill squashes the whole gradient into whatever width it currently has,
815
+ * so a bar at 10% shows the entire orange-to-yellow blend in a sliver and the
816
+ * ramp reads as decoration. A clip reveals it instead, and unlike width it is
817
+ * composited rather than layout-triggering.
818
+ */
819
+ @utility transition-clip {
820
+ transition-property: clip-path;
821
+ transition-timing-function: var(--halogen-easing-move);
822
+ transition-duration: var(--halogen-duration-slow);
823
+ }
824
+
825
+ @utility focus-fade {
826
+ outline: var(--halogen-border-width-2) solid transparent;
827
+ outline-offset: var(--halogen-space-half);
828
+
829
+ /* Supersedes transition-surface rather than composing with it: two rules each
830
+ setting transition-property means the later one wins outright, and the
831
+ first version of this utility was silently overridden — the ring never
832
+ faded. Declared as one full list here, with the ring given a longer
833
+ duration than the colors so the fade is perceptible while hover stays
834
+ snappy. Do not apply transition-surface alongside this. */
835
+ /* The ring gets ease-move at duration-slow; the colors keep ease-enter's
836
+ snap. Measured on the first version: with ease-enter the ring was 38%
837
+ opaque at 27ms and 90% at 79ms — animating correctly and perceptually
838
+ instant. A fade nobody can see is not a fade. */
839
+ transition-property: color, background-color, border-color, outline-color, box-shadow;
840
+ transition-timing-function:
841
+ var(--halogen-easing-enter),
842
+ var(--halogen-easing-enter),
843
+ var(--halogen-easing-enter),
844
+ var(--halogen-easing-move),
845
+ var(--halogen-easing-move);
846
+ transition-duration:
847
+ var(--halogen-duration-fast),
848
+ var(--halogen-duration-fast),
849
+ var(--halogen-duration-fast),
850
+ var(--halogen-duration-slow),
851
+ var(--halogen-duration-slow);
852
+
853
+ &:focus-visible {
854
+ outline-color: var(--halogen-line-focus);
855
+ /* A soft accent halo outside the ring. The ring is still the indicator and
856
+ is still contrast-asserted; this only makes the moment land. */
857
+ box-shadow: 0 0 0 5px var(--halogen-line-focus-glow);
858
+ }
859
+ }