@ponti-studios/ui 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +27 -0
  2. package/dist/index.js +2118 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +130 -0
  5. package/src/animations.css +437 -0
  6. package/src/components/data-display/accordion.stories.tsx +57 -0
  7. package/src/components/data-display/accordion.tsx +65 -0
  8. package/src/components/data-display/filter-chip.tsx +41 -0
  9. package/src/components/data-display/index.ts +13 -0
  10. package/src/components/data-display/table.stories.tsx +75 -0
  11. package/src/components/data-display/table.tsx +84 -0
  12. package/src/components/feedback/alert.stories.tsx +51 -0
  13. package/src/components/feedback/alert.tsx +60 -0
  14. package/src/components/feedback/empty-state.tsx +66 -0
  15. package/src/components/feedback/index.ts +6 -0
  16. package/src/components/feedback/progress.stories.tsx +37 -0
  17. package/src/components/feedback/progress.tsx +30 -0
  18. package/src/components/feedback/spinner.stories.tsx +52 -0
  19. package/src/components/feedback/spinner.tsx +48 -0
  20. package/src/components/forms/calendar.stories.tsx +30 -0
  21. package/src/components/forms/calendar.tsx +67 -0
  22. package/src/components/forms/date-picker.stories.tsx +48 -0
  23. package/src/components/forms/date-picker.tsx +60 -0
  24. package/src/components/forms/field.stories.tsx +62 -0
  25. package/src/components/forms/field.tsx +65 -0
  26. package/src/components/forms/field.types.ts +7 -0
  27. package/src/components/forms/index.ts +24 -0
  28. package/src/components/forms/input.stories.tsx +47 -0
  29. package/src/components/forms/input.tsx +20 -0
  30. package/src/components/forms/radio-group.stories.tsx +48 -0
  31. package/src/components/forms/radio-group.tsx +38 -0
  32. package/src/components/forms/select.stories.tsx +88 -0
  33. package/src/components/forms/select.tsx +147 -0
  34. package/src/components/forms/slider.stories.tsx +67 -0
  35. package/src/components/forms/slider.tsx +25 -0
  36. package/src/components/forms/stepper.stories.tsx +111 -0
  37. package/src/components/forms/stepper.tsx +66 -0
  38. package/src/components/forms/switch.stories.tsx +144 -0
  39. package/src/components/forms/switch.tsx +36 -0
  40. package/src/components/forms/text-field.stories.tsx +87 -0
  41. package/src/components/forms/text-field.tsx +40 -0
  42. package/src/components/forms/text-field.types.ts +9 -0
  43. package/src/components/forms/textarea.stories.tsx +150 -0
  44. package/src/components/forms/textarea.tsx +18 -0
  45. package/src/components/layout/index.ts +2 -0
  46. package/src/components/layout/scroll-area.stories.tsx +83 -0
  47. package/src/components/layout/scroll-area.tsx +40 -0
  48. package/src/components/navigation/app-navigation.stories.tsx +81 -0
  49. package/src/components/navigation/app-navigation.tsx +155 -0
  50. package/src/components/navigation/index.ts +3 -0
  51. package/src/components/navigation/tabs.stories.tsx +69 -0
  52. package/src/components/navigation/tabs.tsx +49 -0
  53. package/src/components/overlays/alert-dialog.stories.tsx +45 -0
  54. package/src/components/overlays/alert-dialog.tsx +119 -0
  55. package/src/components/overlays/command.stories.tsx +65 -0
  56. package/src/components/overlays/command.tsx +130 -0
  57. package/src/components/overlays/dialog.stories.tsx +111 -0
  58. package/src/components/overlays/dialog.tsx +162 -0
  59. package/src/components/overlays/dropdown-menu.stories.tsx +79 -0
  60. package/src/components/overlays/dropdown-menu.tsx +214 -0
  61. package/src/components/overlays/index.ts +65 -0
  62. package/src/components/overlays/popover.stories.tsx +39 -0
  63. package/src/components/overlays/popover.tsx +40 -0
  64. package/src/components/overlays/sheet.stories.tsx +68 -0
  65. package/src/components/overlays/sheet.tsx +98 -0
  66. package/src/components/primitives/avatar.stories.tsx +71 -0
  67. package/src/components/primitives/avatar.tsx +132 -0
  68. package/src/components/primitives/badge.stories.tsx +33 -0
  69. package/src/components/primitives/badge.tsx +44 -0
  70. package/src/components/primitives/button.stories.tsx +113 -0
  71. package/src/components/primitives/button.tsx +95 -0
  72. package/src/components/primitives/button.types.ts +10 -0
  73. package/src/components/primitives/card.stories.tsx +59 -0
  74. package/src/components/primitives/card.tsx +69 -0
  75. package/src/components/primitives/index.ts +13 -0
  76. package/src/components/primitives/label.stories.tsx +47 -0
  77. package/src/components/primitives/label.tsx +21 -0
  78. package/src/constants/chart-colors.ts +39 -0
  79. package/src/env.d.ts +9 -0
  80. package/src/hooks/index.ts +6 -0
  81. package/src/hooks/sort.types.ts +12 -0
  82. package/src/hooks/use-api-client.ts +122 -0
  83. package/src/hooks/use-debounced-value.ts +12 -0
  84. package/src/hooks/use-filter-state.ts +68 -0
  85. package/src/hooks/use-media-query.ts +65 -0
  86. package/src/hooks/use-mobile.tsx +19 -0
  87. package/src/index.ts +25 -0
  88. package/src/lib/auth.ts +5 -0
  89. package/src/lib/clipboard.ts +8 -0
  90. package/src/lib/create-memory-storage.ts +24 -0
  91. package/src/lib/index.ts +4 -0
  92. package/src/lib/utils.ts +6 -0
  93. package/src/storybook/controls.ts +117 -0
  94. package/src/storybook/options.ts +52 -0
  95. package/src/styles.css +1052 -0
  96. package/src/tokens/color-systems.stories.tsx +133 -0
  97. package/src/tokens/colors.ts +156 -0
  98. package/src/tokens/foundations.stories.tsx +151 -0
  99. package/src/tokens/index.ts +16 -0
  100. package/src/tokens/layout.stories.tsx +118 -0
  101. package/src/tokens/motion.ts +51 -0
  102. package/src/tokens/radii.ts +10 -0
  103. package/src/tokens/shadows.ts +34 -0
  104. package/src/tokens/spacing.ts +30 -0
  105. package/src/tokens/typography.ts +42 -0
  106. package/src/translations/en.ts +34 -0
  107. package/src/translations/index.ts +32 -0
  108. package/src/types/upload.ts +42 -0
package/src/styles.css ADDED
@@ -0,0 +1,1052 @@
1
+ @import "tailwindcss";
2
+ @import "./animations.css";
3
+
4
+ /* Shared page and content rhythm primitives. These are CSS-only layout
5
+ * patterns so feature pages can compose them without adding component APIs. */
6
+ .page-shell {
7
+ @apply relative mx-auto flex w-full flex-col gap-12 px-4 py-16 md:gap-16 md:px-6 md:py-20;
8
+ }
9
+
10
+ .page-shell-detail {
11
+ @apply relative mx-auto flex w-full flex-col gap-10 px-4 py-16 md:gap-12 md:px-6 md:py-20;
12
+ }
13
+
14
+ .page-bleed {
15
+ @apply flex w-full flex-col;
16
+ }
17
+
18
+ .layout-stack {
19
+ @apply flex flex-col gap-4;
20
+ }
21
+
22
+ .list-row {
23
+ @apply flex gap-4 px-0 py-6 md:gap-6 md:py-8;
24
+ }
25
+
26
+ .list-media {
27
+ @apply border-subtle bg-panel relative isolate flex shrink-0 items-center justify-center overflow-hidden rounded-md border p-2 shadow-none;
28
+ }
29
+
30
+ .list-media-wide {
31
+ @apply h-14 w-32;
32
+ }
33
+
34
+ .list-media-square {
35
+ @apply size-10 sm:size-12;
36
+ }
37
+
38
+ .list-media-placeholder {
39
+ @apply pointer-events-none absolute inset-0 flex items-center justify-center gap-1.5 transition-opacity duration-150;
40
+ }
41
+
42
+ .section {
43
+ @apply border-subtle flex flex-col gap-4 border-b px-4 py-12 md:px-6 md:py-16;
44
+ }
45
+
46
+ .section-hero {
47
+ @apply gap-6 py-16 md:py-20;
48
+ }
49
+
50
+ .detail-hero {
51
+ @apply gap-4 py-10 md:gap-6 md:py-16;
52
+ }
53
+
54
+ .section-compact {
55
+ @apply gap-4 py-8 md:py-12;
56
+ }
57
+
58
+ .detail-navigation {
59
+ @apply flex flex-col gap-6 sm:flex-row sm:justify-between;
60
+ }
61
+
62
+ .detail-navigation-link {
63
+ @apply flex min-h-11 flex-col justify-center gap-1;
64
+ }
65
+
66
+ .navigation-shell {
67
+ @apply bg-canvas/80 border-subtle sticky top-0 z-50 flex w-full justify-center border-b px-4 backdrop-blur-sm backdrop-saturate-150;
68
+ }
69
+
70
+ .navigation {
71
+ @apply w-full max-w-7xl;
72
+ }
73
+
74
+ .navigation-inner {
75
+ @apply flex min-h-14 items-center justify-between gap-6;
76
+ }
77
+
78
+ .navigation-start,
79
+ .navigation-end,
80
+ .navigation-mobile {
81
+ @apply flex items-center;
82
+ }
83
+
84
+ .navigation-start {
85
+ @apply min-w-0;
86
+ }
87
+
88
+ .navigation-end {
89
+ @apply ml-auto hidden min-w-0 gap-1 sm:flex;
90
+ }
91
+
92
+ .navigation-mobile {
93
+ @apply sm:hidden;
94
+ }
95
+
96
+ .navigation-panel-links {
97
+ @apply mt-8 flex flex-1 flex-col gap-1;
98
+ }
99
+
100
+ .navigation-panel-end {
101
+ @apply border-default flex flex-col gap-4 border-t pt-4;
102
+ }
103
+
104
+ .navigation-panel-content {
105
+ @apply flex items-center gap-3;
106
+ }
107
+
108
+ .navigation-link {
109
+ @apply inline-flex min-h-11 shrink-0 items-center justify-center gap-1.5 rounded-md border border-transparent px-3 py-1.5 text-sm leading-5 font-medium whitespace-nowrap transition-colors duration-150;
110
+ }
111
+
112
+ .navigation-link:hover {
113
+ @apply bg-surface-hover text-primary;
114
+ }
115
+
116
+ .navigation-link:active {
117
+ @apply bg-surface-pressed;
118
+ }
119
+
120
+ .navigation-link[aria-current="page"] {
121
+ @apply bg-panel text-primary;
122
+ }
123
+
124
+ .navigation-link[aria-current="page"]:hover {
125
+ @apply bg-surface-hover;
126
+ }
127
+
128
+ .navigation-brand {
129
+ @apply border-transparent bg-transparent px-2;
130
+ }
131
+
132
+ .navigation-cta {
133
+ @apply inline-flex min-h-11 shrink-0 items-center justify-center gap-1.5 rounded-md border px-3 py-1.5 text-sm leading-5 font-medium whitespace-nowrap transition-colors duration-150;
134
+ }
135
+
136
+ .navigation-end > .navigation-cta {
137
+ @apply ml-2;
138
+ }
139
+
140
+ .navigation-panel-links .navigation-link,
141
+ .navigation-panel-links .navigation-cta,
142
+ .navigation-panel-end .navigation-cta {
143
+ @apply w-full justify-start;
144
+ }
145
+
146
+ .navigation-cta[data-variant="outline"] {
147
+ @apply border-default text-primary bg-transparent;
148
+ }
149
+
150
+ .navigation-cta[data-variant="outline"]:hover {
151
+ @apply bg-surface-hover;
152
+ }
153
+
154
+ .navigation-cta[data-variant="outline"]:active {
155
+ @apply bg-surface-pressed;
156
+ }
157
+
158
+ .navigation-cta:not([data-variant="outline"]) {
159
+ @apply bg-accent text-on-accent border-transparent;
160
+ }
161
+
162
+ .navigation-cta:not([data-variant="outline"]):hover {
163
+ @apply bg-accent-hover;
164
+ }
165
+
166
+ .navigation-cta:not([data-variant="outline"]):active {
167
+ @apply bg-accent-pressed;
168
+ }
169
+
170
+ /* Overlay material: an intentional surface, not a raw token name in markup. */
171
+ .overlay-backdrop {
172
+ background: var(--color-overlay-scrim);
173
+ backdrop-filter: blur(8px) saturate(85%);
174
+ }
175
+
176
+ .sheet-edge-left::before,
177
+ .sheet-edge-right::before {
178
+ top: 0;
179
+ bottom: 0;
180
+ width: 9rem;
181
+ background: radial-gradient(
182
+ ellipse at center,
183
+ color-mix(in srgb, var(--color-accent) 14%, transparent),
184
+ transparent 70%
185
+ );
186
+ }
187
+
188
+ .sheet-edge-left::before {
189
+ left: -5rem;
190
+ }
191
+
192
+ .sheet-edge-right::before {
193
+ right: -5rem;
194
+ }
195
+
196
+ .sheet-edge-top::before,
197
+ .sheet-edge-bottom::before {
198
+ right: 0;
199
+ left: 0;
200
+ height: 9rem;
201
+ background: radial-gradient(
202
+ ellipse at center,
203
+ color-mix(in srgb, var(--color-accent) 14%, transparent),
204
+ transparent 70%
205
+ );
206
+ }
207
+
208
+ .sheet-edge-top::before {
209
+ top: -5rem;
210
+ }
211
+
212
+ .sheet-edge-bottom::before {
213
+ bottom: -5rem;
214
+ }
215
+
216
+ .sheet-edge-top::after,
217
+ .sheet-edge-bottom::after {
218
+ right: 8%;
219
+ left: 8%;
220
+ height: 1px;
221
+ background: linear-gradient(
222
+ 90deg,
223
+ transparent,
224
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 32%,
225
+ color-mix(in srgb, var(--color-accent) 40%, transparent) 50%,
226
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 68%,
227
+ transparent
228
+ );
229
+ }
230
+
231
+ .sheet-edge-top::after {
232
+ top: 0;
233
+ }
234
+
235
+ .sheet-edge-bottom::after {
236
+ bottom: 0;
237
+ }
238
+
239
+ .sheet-edge-left::after,
240
+ .sheet-edge-right::after {
241
+ top: 8%;
242
+ bottom: 8%;
243
+ width: 1px;
244
+ background: linear-gradient(
245
+ 180deg,
246
+ transparent,
247
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 32%,
248
+ color-mix(in srgb, var(--color-accent) 40%, transparent) 50%,
249
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 68%,
250
+ transparent
251
+ );
252
+ }
253
+
254
+ .sheet-edge-left::after {
255
+ left: 0;
256
+ }
257
+
258
+ .sheet-edge-right::after {
259
+ right: 0;
260
+ }
261
+
262
+ .sheet-edge-responsive::before {
263
+ top: -5rem;
264
+ right: 0;
265
+ left: 0;
266
+ height: 9rem;
267
+ background: radial-gradient(
268
+ ellipse at center,
269
+ color-mix(in srgb, var(--color-accent) 14%, transparent),
270
+ transparent 70%
271
+ );
272
+ }
273
+
274
+ .sheet-edge-responsive::after {
275
+ top: 0;
276
+ right: 8%;
277
+ left: 8%;
278
+ height: 1px;
279
+ background: linear-gradient(
280
+ 90deg,
281
+ transparent,
282
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 32%,
283
+ color-mix(in srgb, var(--color-accent) 40%, transparent) 50%,
284
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 68%,
285
+ transparent
286
+ );
287
+ }
288
+
289
+ @media (min-width: 768px) {
290
+ .sheet-edge-responsive::before {
291
+ top: 0;
292
+ right: -5rem;
293
+ bottom: 0;
294
+ left: auto;
295
+ width: 9rem;
296
+ height: auto;
297
+ }
298
+
299
+ .sheet-edge-responsive::after {
300
+ top: 8%;
301
+ right: 0;
302
+ bottom: 8%;
303
+ left: auto;
304
+ width: 1px;
305
+ height: auto;
306
+ background: linear-gradient(
307
+ 180deg,
308
+ transparent,
309
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 32%,
310
+ color-mix(in srgb, var(--color-accent) 40%, transparent) 50%,
311
+ color-mix(in srgb, var(--color-text-primary) 24%, transparent) 68%,
312
+ transparent
313
+ );
314
+ }
315
+ }
316
+
317
+ .sheet-glass-control {
318
+ background: color-mix(in srgb, var(--color-surface-raised) 62%, transparent);
319
+ backdrop-filter: blur(12px);
320
+ }
321
+
322
+ @theme {
323
+ --font-family-primary: -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
324
+ --font-family-mono: ui-monospace, monospace;
325
+
326
+ /* Public utility names for the canonical surface roles. */
327
+ --color-canvas: var(--color-surface-canvas);
328
+ --color-panel: var(--color-surface-panel);
329
+ --color-raised: var(--color-surface-raised);
330
+ --color-inset: var(--color-surface-inset);
331
+ --color-focus: var(--color-ring-focus);
332
+
333
+ --font-size-large-title: 34px;
334
+ --font-size-title-1: 28px;
335
+ --font-size-title-2: 22px;
336
+ --font-size-title-3: 20px;
337
+ --font-size-headline: 17px;
338
+ --font-size-body: 17px;
339
+ --font-size-callout: 16px;
340
+ --font-size-subhead: 15px;
341
+ --font-size-footnote: 13px;
342
+ --font-size-caption-1: 12px;
343
+ --font-size-caption-2: 11px;
344
+
345
+ --font-size-xs: 12px;
346
+ --font-size-sm: 14px;
347
+ --font-size-md: 16px;
348
+ --font-size-lg: 18px;
349
+ --font-size-xl: 20px;
350
+ --font-size-display: 34px;
351
+
352
+ --font-weight-regular: 400;
353
+ --font-weight-medium: 500;
354
+ --font-weight-semibold: 600;
355
+ --font-weight-bold: 700;
356
+
357
+ --line-height-tight: 1.2;
358
+ --line-height-normal: 1.4;
359
+ --line-height-relaxed: 1.6;
360
+
361
+ --letter-spacing-tight: -0.025em;
362
+ --letter-spacing-normal: 0;
363
+ --letter-spacing-relaxed: 0.01em;
364
+
365
+ /* Canonical Ponti light fallback values used for utility generation. */
366
+ --color-surface-canvas: #ffffff;
367
+ --color-surface-panel: #f6f8fa;
368
+ --color-surface-raised: #ffffff;
369
+ --color-surface-inset: color-mix(
370
+ in srgb,
371
+ var(--color-surface-canvas) 94%,
372
+ var(--color-text-primary) 6%
373
+ );
374
+ --color-overlay-scrim: rgba(31, 35, 40, 0.18);
375
+
376
+ --color-text-primary: #25292e;
377
+ --color-text-secondary: #59636e;
378
+ --color-text-tertiary: #818b98;
379
+ --color-text-disabled: #9ea7b3;
380
+ --color-text-accent: var(--color-accent);
381
+ --color-text-destructive: var(--color-destructive);
382
+ --color-text-success: var(--color-success);
383
+ --color-text-warning: var(--color-warning);
384
+ --color-text-on-success: #ffffff;
385
+ --color-text-on-warning: #1c1c1e;
386
+
387
+ --color-border-default: #d1d9e0;
388
+ --color-border-subtle: rgba(129, 139, 152, 0.2);
389
+ --color-border-strong: #8c959f;
390
+ --color-border-focus: #0969da;
391
+ --color-border-accent: var(--color-accent);
392
+ --color-border-destructive: var(--color-destructive);
393
+
394
+ --color-success: #1f883d;
395
+ --color-warning: #9a6700;
396
+ --color-destructive: #cf222e;
397
+ --color-destructive-hover: color-mix(in srgb, var(--color-destructive) 88%, white 12%);
398
+ --color-destructive-pressed: color-mix(in srgb, var(--color-destructive) 78%, black 22%);
399
+ --color-destructive-subtle: color-mix(in srgb, var(--color-destructive) 14%, transparent);
400
+
401
+ --color-accent: #0969da;
402
+ --color-text-on-accent: #ffffff;
403
+ --color-accent-hover: color-mix(in srgb, var(--color-accent) 88%, white 12%);
404
+ --color-accent-pressed: color-mix(in srgb, var(--color-accent) 78%, black 22%);
405
+ --color-accent-subtle: color-mix(in srgb, var(--color-accent) 14%, transparent);
406
+
407
+ --color-text-on-destructive: #ffffff;
408
+ --color-ring-focus: #0969da;
409
+
410
+ --color-chart-1: #0969da;
411
+ --color-chart-2: #1a7f37;
412
+ --color-chart-3: #8250df;
413
+ --color-chart-4: #bc4c00;
414
+ --color-chart-5: #59636e;
415
+ --color-chart-positive: #1a7f37;
416
+ --color-chart-negative: #cf222e;
417
+ --color-chart-neutral: #59636e;
418
+
419
+ --color-surface-hover: color-mix(
420
+ in srgb,
421
+ var(--color-surface-panel) 88%,
422
+ var(--color-text-primary) 12%
423
+ );
424
+ --color-surface-pressed: color-mix(
425
+ in srgb,
426
+ var(--color-surface-panel) 78%,
427
+ var(--color-text-primary) 22%
428
+ );
429
+ --color-surface-selected: var(--color-accent-subtle);
430
+ --color-surface-disabled: var(--color-surface-inset);
431
+
432
+ --spacing-1: 4px;
433
+ --spacing-2: 8px;
434
+ --spacing-3: 12px;
435
+ --spacing-4: 16px;
436
+ --spacing-5: 24px;
437
+ --spacing-6: 32px;
438
+ --spacing-7: 48px;
439
+ --spacing-8: 64px;
440
+
441
+ --content-width-bubble: 36rem;
442
+ --content-width-transcript: 44rem;
443
+ --content-width-note-preview: 32ch;
444
+
445
+ --radius-sm: 4px;
446
+ --radius-md: 6px;
447
+ --radius-lg: 8px;
448
+ --radius-xl: 12px;
449
+ --radius-icon: 22%;
450
+ --radius: 4px;
451
+
452
+ --shadow-low: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.12);
453
+ --shadow-medium: 0 4px 16px rgba(0, 0, 0, 0.24), 0 2px 4px rgba(0, 0, 0, 0.12);
454
+ --shadow-high: 0 16px 48px rgba(0, 0, 0, 0.32), 0 4px 12px rgba(0, 0, 0, 0.18);
455
+
456
+ --duration-fast: 120ms;
457
+ --duration-default: 200ms;
458
+ --duration-slow: 320ms;
459
+ --ease-default: cubic-bezier(0.25, 0.46, 0.45, 0.94);
460
+ --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
461
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
462
+ }
463
+
464
+ :root {
465
+ color-scheme: light dark;
466
+ --color-surface-canvas: #ffffff;
467
+ --color-surface-panel: #f6f8fa;
468
+ --color-surface-raised: #ffffff;
469
+ --color-overlay-scrim: rgba(31, 35, 40, 0.42);
470
+ --color-text-primary: #25292e;
471
+ --color-text-secondary: #59636e;
472
+ --color-text-tertiary: #818b98;
473
+ --color-text-disabled: #9ea7b3;
474
+ --color-border-default: #d1d9e0;
475
+ --color-border-subtle: rgba(129, 139, 152, 0.2);
476
+ --color-border-strong: #8c959f;
477
+ --color-border-focus: #0969da;
478
+ --color-border-accent: #0969da;
479
+ --color-border-destructive: #cf222e;
480
+ --color-text-accent: #0969da;
481
+ --color-text-destructive: #cf222e;
482
+ --color-text-success: #1f883d;
483
+ --color-text-warning: #9a6700;
484
+ --color-text-on-accent: #ffffff;
485
+ --color-text-on-destructive: #ffffff;
486
+ --color-text-on-success: #ffffff;
487
+ --color-text-on-warning: #1c1c1e;
488
+ --color-success: #1f883d;
489
+ --color-success-subtle: rgba(31, 136, 61, 0.12);
490
+ --color-warning: #9a6700;
491
+ --color-warning-subtle: rgba(154, 103, 0, 0.12);
492
+ --color-destructive: #cf222e;
493
+ --color-destructive-hover: #a40e26;
494
+ --color-destructive-pressed: #82071e;
495
+ --color-destructive-subtle: rgba(207, 34, 46, 0.12);
496
+ --color-accent: #0969da;
497
+ --color-accent-hover: #0550ae;
498
+ --color-accent-pressed: #033d8b;
499
+ --color-accent-subtle: rgba(9, 105, 218, 0.1);
500
+ --color-ring-focus: #0969da;
501
+ --color-chart-1: #0969da;
502
+ --color-chart-2: #1a7f37;
503
+ --color-chart-3: #8250df;
504
+ --color-chart-4: #bc4c00;
505
+ --color-chart-5: #59636e;
506
+ --color-chart-positive: #1a7f37;
507
+ --color-chart-negative: #cf222e;
508
+ --color-chart-neutral: #59636e;
509
+ }
510
+
511
+ :root[data-color-mode="dark"] {
512
+ color-scheme: dark;
513
+ --color-surface-canvas: #0d1117;
514
+ --color-surface-panel: #161b22;
515
+ --color-surface-raised: #21262d;
516
+ --color-overlay-scrim: rgba(1, 4, 9, 0.78);
517
+ --color-text-primary: #f0f6fc;
518
+ --color-text-secondary: #8b949e;
519
+ --color-text-tertiary: #6e7681;
520
+ --color-text-disabled: #484f58;
521
+ --color-border-default: #30363d;
522
+ --color-border-subtle: rgba(240, 246, 252, 0.14);
523
+ --color-border-strong: #6e7681;
524
+ --color-border-focus: #2f81f7;
525
+ --color-border-accent: #2f81f7;
526
+ --color-border-destructive: #da3633;
527
+ --color-text-accent: #58a6ff;
528
+ --color-text-destructive: #ff7b72;
529
+ --color-text-success: #3fb950;
530
+ --color-text-warning: #d29922;
531
+ --color-text-on-warning: #0d1117;
532
+ --color-success: #238636;
533
+ --color-success-subtle: rgba(35, 134, 54, 0.18);
534
+ --color-warning: #9e6a03;
535
+ --color-warning-subtle: rgba(158, 106, 3, 0.18);
536
+ --color-destructive: #da3633;
537
+ --color-destructive-hover: #f85149;
538
+ --color-destructive-pressed: #b62324;
539
+ --color-destructive-subtle: rgba(218, 54, 51, 0.18);
540
+ --color-accent: #2f81f7;
541
+ --color-accent-hover: #58a6ff;
542
+ --color-accent-pressed: #1f6feb;
543
+ --color-accent-subtle: rgba(47, 129, 247, 0.18);
544
+ --color-ring-focus: #2f81f7;
545
+ --color-chart-1: #2f81f7;
546
+ --color-chart-2: #3fb950;
547
+ --color-chart-3: #a371f7;
548
+ --color-chart-4: #d29922;
549
+ --color-chart-5: #8b949e;
550
+ --color-chart-positive: #3fb950;
551
+ --color-chart-negative: #f85149;
552
+ --color-chart-neutral: #8b949e;
553
+ }
554
+
555
+ @media (prefers-color-scheme: dark) {
556
+ :root:not([data-color-mode]) {
557
+ color-scheme: dark;
558
+ --color-surface-canvas: #0d1117;
559
+ --color-surface-panel: #161b22;
560
+ --color-surface-raised: #21262d;
561
+ --color-overlay-scrim: rgba(1, 4, 9, 0.78);
562
+ --color-text-primary: #f0f6fc;
563
+ --color-text-secondary: #8b949e;
564
+ --color-text-tertiary: #6e7681;
565
+ --color-text-disabled: #484f58;
566
+ --color-border-default: #30363d;
567
+ --color-border-subtle: rgba(240, 246, 252, 0.14);
568
+ --color-border-strong: #6e7681;
569
+ --color-border-focus: #2f81f7;
570
+ --color-border-accent: #2f81f7;
571
+ --color-border-destructive: #da3633;
572
+ --color-text-accent: #58a6ff;
573
+ --color-text-destructive: #ff7b72;
574
+ --color-text-success: #3fb950;
575
+ --color-text-warning: #d29922;
576
+ --color-text-on-warning: #0d1117;
577
+ --color-success: #238636;
578
+ --color-success-subtle: rgba(35, 134, 54, 0.18);
579
+ --color-warning: #9e6a03;
580
+ --color-warning-subtle: rgba(158, 106, 3, 0.18);
581
+ --color-destructive: #da3633;
582
+ --color-destructive-hover: #f85149;
583
+ --color-destructive-pressed: #b62324;
584
+ --color-destructive-subtle: rgba(218, 54, 51, 0.18);
585
+ --color-accent: #2f81f7;
586
+ --color-accent-hover: #58a6ff;
587
+ --color-accent-pressed: #1f6feb;
588
+ --color-accent-subtle: rgba(47, 129, 247, 0.18);
589
+ --color-ring-focus: #2f81f7;
590
+ --color-chart-1: #2f81f7;
591
+ --color-chart-2: #3fb950;
592
+ --color-chart-3: #a371f7;
593
+ --color-chart-4: #d29922;
594
+ --color-chart-5: #8b949e;
595
+ --color-chart-positive: #3fb950;
596
+ --color-chart-negative: #f85149;
597
+ --color-chart-neutral: #8b949e;
598
+ }
599
+ }
600
+ @utility pb-safe-area-inset-bottom {
601
+ padding-bottom: env(safe-area-inset-bottom);
602
+ }
603
+
604
+ @utility mb-safe-area-inset-bottom {
605
+ margin-bottom: env(safe-area-inset-bottom);
606
+ }
607
+
608
+ @utility min-h-screen {
609
+ min-height: 100vh;
610
+ min-height: 100dvh;
611
+ }
612
+
613
+ @utility min-h-screen-dynamic {
614
+ min-height: 100dvh;
615
+ }
616
+
617
+ @utility h-screen {
618
+ height: 100vh;
619
+ height: 100dvh;
620
+ }
621
+
622
+ @layer base {
623
+ html,
624
+ body {
625
+ font-family: var(--font-family-primary);
626
+ color-scheme: light dark;
627
+ background-color: var(--color-surface-canvas);
628
+ color: var(--color-text-primary);
629
+ -webkit-font-smoothing: antialiased;
630
+ -moz-osx-font-smoothing: grayscale;
631
+ }
632
+
633
+ *:focus {
634
+ outline: none;
635
+ }
636
+
637
+ *:focus-visible {
638
+ outline: 2px solid var(--color-ring-focus);
639
+ outline-offset: 2px;
640
+ border-radius: inherit;
641
+ }
642
+
643
+ * {
644
+ transition: none;
645
+ }
646
+
647
+ *:is(button, a, input, select, textarea, [role="button"], [role="link"]) {
648
+ transition-property: background-color, color, border-color, opacity;
649
+ transition-duration: var(--duration-fast);
650
+ transition-timing-function: var(--ease-default);
651
+ }
652
+
653
+ *,
654
+ ::after,
655
+ ::before,
656
+ ::backdrop,
657
+ ::file-selector-button {
658
+ border-color: var(--color-border-default, currentColor);
659
+ }
660
+
661
+ button {
662
+ cursor: pointer;
663
+ font-family: inherit;
664
+ }
665
+
666
+ [data-radix-portal] {
667
+ z-index: 9999;
668
+ }
669
+
670
+ h1,
671
+ h2,
672
+ h3,
673
+ h4,
674
+ h5,
675
+ h6 {
676
+ font-family: var(--font-family-primary);
677
+ font-weight: var(--font-weight-semibold);
678
+ letter-spacing: var(--letter-spacing-tight);
679
+ }
680
+
681
+ @media (prefers-reduced-motion: reduce) {
682
+ * {
683
+ animation-duration: 0.01ms !important;
684
+ animation-iteration-count: 1 !important;
685
+ transition-duration: 0.01ms !important;
686
+ }
687
+ }
688
+ }
689
+
690
+ @utility bg-canvas {
691
+ background-color: var(--color-surface-canvas);
692
+ }
693
+
694
+ @utility bg-panel {
695
+ background-color: var(--color-surface-panel);
696
+ }
697
+
698
+ @utility bg-raised {
699
+ background-color: var(--color-surface-raised);
700
+ }
701
+
702
+ @utility bg-inset {
703
+ background-color: var(--color-surface-inset);
704
+ }
705
+
706
+ @utility bg-overlay-scrim {
707
+ background-color: var(--color-overlay-scrim);
708
+ }
709
+
710
+ @utility text-primary {
711
+ color: var(--color-text-primary);
712
+ }
713
+
714
+ @utility text-secondary {
715
+ color: var(--color-text-secondary);
716
+ }
717
+
718
+ @utility text-tertiary {
719
+ color: var(--color-text-tertiary);
720
+ }
721
+
722
+ @utility text-disabled {
723
+ color: var(--color-text-disabled);
724
+ }
725
+
726
+ @utility text-on-accent {
727
+ color: var(--color-text-on-accent);
728
+ }
729
+
730
+ @utility text-on-destructive {
731
+ color: var(--color-text-on-destructive);
732
+ }
733
+
734
+ @utility ring-focus {
735
+ --tw-ring-color: var(--color-ring-focus);
736
+ }
737
+
738
+ @utility border-default {
739
+ border-color: var(--color-border-default);
740
+ }
741
+
742
+ @utility border-subtle {
743
+ border-color: var(--color-border-subtle);
744
+ }
745
+
746
+ @utility border-focus {
747
+ border-color: var(--color-border-focus);
748
+ }
749
+
750
+ @utility display-1 {
751
+ font-size: clamp(2.5rem, 5vw, 6rem);
752
+ font-family: var(--font-family-primary);
753
+ font-weight: var(--font-weight-bold);
754
+ line-height: 1.1;
755
+ letter-spacing: var(--letter-spacing-tight);
756
+ }
757
+
758
+ @utility display-2 {
759
+ font-size: clamp(2rem, 3vw, 3.5rem);
760
+ font-family: var(--font-family-primary);
761
+ font-weight: var(--font-weight-bold);
762
+ line-height: 1.15;
763
+ letter-spacing: var(--letter-spacing-tight);
764
+ }
765
+
766
+ @utility heading-1 {
767
+ font-size: clamp(2rem, 3vw, 2.75rem);
768
+ font-family: var(--font-family-primary);
769
+ font-weight: var(--font-weight-semibold);
770
+ line-height: 1.2;
771
+ letter-spacing: var(--letter-spacing-tight);
772
+ }
773
+
774
+ @utility heading-2 {
775
+ font-size: clamp(1.375rem, 2vw, 1.75rem);
776
+ font-family: var(--font-family-primary);
777
+ font-weight: var(--font-weight-semibold);
778
+ line-height: 1.25;
779
+ letter-spacing: -0.02em;
780
+ }
781
+
782
+ @utility heading-3 {
783
+ font-size: clamp(1.125rem, 1.5vw, 1.375rem);
784
+ font-family: var(--font-family-primary);
785
+ font-weight: var(--font-weight-semibold);
786
+ line-height: 1.3;
787
+ letter-spacing: -0.015em;
788
+ }
789
+
790
+ @utility heading-4 {
791
+ font-size: clamp(1rem, 1.25vw, 1.125rem);
792
+ font-family: var(--font-family-primary);
793
+ font-weight: var(--font-weight-semibold);
794
+ line-height: 1.4;
795
+ letter-spacing: -0.01em;
796
+ }
797
+
798
+ @utility largeTitle {
799
+ font-size: var(--font-size-large-title);
800
+ font-family: var(--font-family-primary);
801
+ font-weight: var(--font-weight-bold);
802
+ line-height: 1.1;
803
+ letter-spacing: var(--letter-spacing-tight);
804
+ }
805
+
806
+ @utility title1 {
807
+ font-size: var(--font-size-title-1);
808
+ font-family: var(--font-family-primary);
809
+ font-weight: var(--font-weight-bold);
810
+ line-height: 1.2;
811
+ letter-spacing: var(--letter-spacing-tight);
812
+ }
813
+
814
+ @utility headline {
815
+ font-size: var(--font-size-headline);
816
+ font-family: var(--font-family-primary);
817
+ font-weight: var(--font-weight-semibold);
818
+ line-height: 1.3;
819
+ letter-spacing: -0.01em;
820
+ }
821
+
822
+ @utility body {
823
+ font-size: var(--font-size-body);
824
+ font-family: var(--font-family-primary);
825
+ font-weight: var(--font-weight-regular);
826
+ line-height: 1.4;
827
+ letter-spacing: var(--letter-spacing-normal);
828
+ }
829
+
830
+ @utility callout {
831
+ font-size: var(--font-size-callout);
832
+ font-family: var(--font-family-primary);
833
+ font-weight: var(--font-weight-regular);
834
+ line-height: 1.38;
835
+ letter-spacing: var(--letter-spacing-normal);
836
+ }
837
+
838
+ @utility subhead {
839
+ font-size: var(--font-size-subhead);
840
+ font-family: var(--font-family-primary);
841
+ font-weight: var(--font-weight-regular);
842
+ line-height: 1.33;
843
+ letter-spacing: var(--letter-spacing-normal);
844
+ }
845
+
846
+ @utility footnote {
847
+ font-size: var(--font-size-footnote);
848
+ font-family: var(--font-family-primary);
849
+ font-weight: var(--font-weight-regular);
850
+ line-height: 1.38;
851
+ letter-spacing: var(--letter-spacing-normal);
852
+ }
853
+
854
+ @utility caption1 {
855
+ font-size: var(--font-size-caption-1);
856
+ font-family: var(--font-family-primary);
857
+ font-weight: var(--font-weight-regular);
858
+ line-height: 1.33;
859
+ letter-spacing: var(--letter-spacing-normal);
860
+ }
861
+
862
+ @utility caption2 {
863
+ font-size: var(--font-size-caption-2);
864
+ font-family: var(--font-family-primary);
865
+ font-weight: var(--font-weight-medium);
866
+ line-height: 1.27;
867
+ letter-spacing: var(--letter-spacing-normal);
868
+ }
869
+
870
+ @utility mono {
871
+ font-size: var(--font-size-caption-1);
872
+ font-family: var(--font-family-mono);
873
+ font-weight: var(--font-weight-regular);
874
+ line-height: 1.33;
875
+ letter-spacing: var(--letter-spacing-normal);
876
+ }
877
+
878
+ @utility body-1 {
879
+ font-size: clamp(1rem, 1.25vw, 1.0625rem);
880
+ font-family: var(--font-family-primary);
881
+ font-weight: var(--font-weight-regular);
882
+ line-height: 1.6;
883
+ letter-spacing: var(--letter-spacing-normal);
884
+ }
885
+
886
+ @utility body-2 {
887
+ font-size: clamp(0.875rem, 1vw, 1rem);
888
+ font-family: var(--font-family-primary);
889
+ font-weight: var(--font-weight-regular);
890
+ line-height: 1.5;
891
+ letter-spacing: var(--letter-spacing-normal);
892
+ }
893
+
894
+ @utility body-3 {
895
+ font-size: 0.9375rem;
896
+ font-family: var(--font-family-primary);
897
+ font-weight: var(--font-weight-regular);
898
+ line-height: 1.47;
899
+ letter-spacing: -0.015em;
900
+ }
901
+
902
+ @utility body-4 {
903
+ font-size: 0.8125rem;
904
+ font-family: var(--font-family-primary);
905
+ font-weight: var(--font-weight-regular);
906
+ line-height: 1.38;
907
+ letter-spacing: -0.005em;
908
+ }
909
+
910
+ @utility subheading-1 {
911
+ font-size: clamp(1.125rem, 1.5vw, 1.375rem);
912
+ font-family: var(--font-family-primary);
913
+ font-weight: var(--font-weight-medium);
914
+ line-height: 1.35;
915
+ letter-spacing: -0.02em;
916
+ }
917
+
918
+ @utility subheading-2 {
919
+ font-size: clamp(1rem, 1.25vw, 1.25rem);
920
+ font-family: var(--font-family-primary);
921
+ font-weight: var(--font-weight-medium);
922
+ line-height: 1.4;
923
+ letter-spacing: -0.015em;
924
+ }
925
+
926
+ @utility subheading-3 {
927
+ font-size: 1rem;
928
+ font-family: var(--font-family-primary);
929
+ font-weight: var(--font-weight-medium);
930
+ line-height: 1.33;
931
+ letter-spacing: -0.01em;
932
+ }
933
+
934
+ @utility subheading-4 {
935
+ font-size: 0.9375rem;
936
+ font-family: var(--font-family-primary);
937
+ font-weight: var(--font-weight-medium);
938
+ line-height: 1.33;
939
+ letter-spacing: -0.008em;
940
+ }
941
+
942
+ @utility hover-surface {
943
+ transition-property: background-color, color, border-color, opacity;
944
+ transition-duration: var(--duration-fast);
945
+ transition-timing-function: var(--ease-default);
946
+
947
+ @media (hover: hover) {
948
+ &:not(:disabled):not([data-disabled]):hover {
949
+ background-color: var(--color-surface-hover);
950
+ border-color: var(--color-border-default);
951
+ color: var(--color-text-primary);
952
+ }
953
+ }
954
+ }
955
+
956
+ @utility list-row {
957
+ display: flex;
958
+ align-items: stretch;
959
+
960
+ & > * {
961
+ display: flex;
962
+ align-items: center;
963
+ }
964
+ }
965
+
966
+ @utility content-width-bubble {
967
+ max-inline-size: var(--content-width-bubble);
968
+ }
969
+
970
+ @utility content-width-transcript {
971
+ max-inline-size: var(--content-width-transcript);
972
+ }
973
+
974
+ @utility content-width-note-preview {
975
+ max-inline-size: var(--content-width-note-preview);
976
+ }
977
+
978
+ @utility ui-eyebrow {
979
+ font-size: var(--font-size-caption-1);
980
+ font-weight: var(--font-weight-medium);
981
+ text-transform: uppercase;
982
+ letter-spacing: 0.16em;
983
+ color: var(--color-text-secondary);
984
+ }
985
+
986
+ @utility ui-plain-card {
987
+ border: 1px solid var(--color-border-default);
988
+ padding: 1.75rem;
989
+ }
990
+
991
+ @utility ui-flat-card {
992
+ border: 1px solid var(--color-border-default);
993
+ background-color: var(--color-surface-panel);
994
+ border-radius: var(--radius-md);
995
+ padding: 1rem;
996
+ }
997
+
998
+ @utility ui-data-value {
999
+ font-size: 1.5rem;
1000
+ font-weight: var(--font-weight-regular);
1001
+ font-variant-numeric: tabular-nums;
1002
+ color: var(--color-text-primary);
1003
+ }
1004
+
1005
+ @utility ui-data-label {
1006
+ font-size: var(--font-size-caption-1);
1007
+ font-weight: var(--font-weight-medium);
1008
+ text-transform: uppercase;
1009
+ letter-spacing: 0.16em;
1010
+ color: var(--color-text-secondary);
1011
+ }
1012
+
1013
+ @utility ui-dash-list-item {
1014
+ display: flex;
1015
+ gap: 0.5rem;
1016
+ font-size: var(--font-size-sm);
1017
+ line-height: 1.5rem;
1018
+ color: var(--color-text-primary);
1019
+ }
1020
+
1021
+ @utility ui-dash-marker {
1022
+ margin-top: 0.125rem;
1023
+ flex-shrink: 0;
1024
+ color: var(--color-text-secondary);
1025
+ }
1026
+
1027
+ @utility scrollbar-hide {
1028
+ -ms-overflow-style: none;
1029
+ scrollbar-width: none;
1030
+ &::-webkit-scrollbar {
1031
+ display: none;
1032
+ }
1033
+ }
1034
+
1035
+ @layer utilities {
1036
+ .container {
1037
+ width: 100%;
1038
+ padding-inline: 1rem;
1039
+ margin-inline: auto;
1040
+ }
1041
+
1042
+ @media (min-width: 640px) {
1043
+ .container {
1044
+ padding-inline: 1.5rem;
1045
+ }
1046
+ }
1047
+ }
1048
+
1049
+ /* Links share one focus language; individual links should not need to opt in. */
1050
+ a:focus-visible {
1051
+ @apply ring-focus ring-2 ring-offset-2 outline-none;
1052
+ }