@hemerson/design-system 0.0.0-stage → 0.2.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -2
  3. package/dist/components/Badge/Badge.d.ts +14 -0
  4. package/dist/components/Button/Button.d.ts +17 -0
  5. package/dist/components/Button/index.d.ts +2 -0
  6. package/dist/components/Card/Card.d.ts +19 -0
  7. package/dist/components/Checkbox/Checkbox.d.ts +8 -0
  8. package/dist/components/Container/Container.d.ts +9 -0
  9. package/dist/components/Dialog/Dialog.d.ts +18 -0
  10. package/dist/components/FloatingButton/FloatingButton.d.ts +9 -0
  11. package/dist/components/GlassPanel/GlassPanel.d.ts +13 -0
  12. package/dist/components/GlowAvatar/GlowAvatar.d.ts +10 -0
  13. package/dist/components/Input/Input.d.ts +12 -0
  14. package/dist/components/Loading/Loading.d.ts +11 -0
  15. package/dist/components/Menu/Menu.d.ts +25 -0
  16. package/dist/components/NavBar/NavBar.d.ts +20 -0
  17. package/dist/components/ScrollArea/ScrollArea.d.ts +8 -0
  18. package/dist/components/SectionTitle/SectionTitle.d.ts +12 -0
  19. package/dist/components/SegmentedControl/SegmentedControl.d.ts +21 -0
  20. package/dist/components/Select/Select.d.ts +16 -0
  21. package/dist/components/Separator/Separator.d.ts +8 -0
  22. package/dist/components/Sidebar/Sidebar.d.ts +21 -0
  23. package/dist/components/Table/Table.d.ts +26 -0
  24. package/dist/components/Toast/Toast.d.ts +16 -0
  25. package/dist/enableGlassRefraction-CgDeg-2E.js +88 -0
  26. package/dist/enableGlassRefraction-CgDeg-2E.js.map +1 -0
  27. package/dist/glass/enableGlassRefraction.d.ts +10 -0
  28. package/dist/glass/index.d.ts +1 -0
  29. package/dist/glass/lens.d.ts +15 -0
  30. package/dist/glass.js +1 -0
  31. package/dist/index.d.ts +42 -0
  32. package/dist/index.js +680 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/internal/Icon.d.ts +17 -0
  35. package/dist/internal/cx.d.ts +2 -0
  36. package/dist/internal/field.d.ts +16 -0
  37. package/dist/styles.css +1297 -0
  38. package/dist/tokens.css +190 -0
  39. package/dist/tokens.json +538 -0
  40. package/package.json +95 -4
@@ -0,0 +1,1297 @@
1
+ /* Raleway for text, JetBrains Mono for numerals. Projects that self-host the
2
+ fonts can import tokens.css and components.css instead of styles.css. */
3
+ @import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@500;700&family=Raleway:wght@400;500;600;700&display=swap");
4
+
5
+ /* Generated from tokens/tokens.json by scripts/build-tokens.mjs. Do not edit. */
6
+
7
+ :root,
8
+ [data-theme="dark"] {
9
+ color-scheme: dark;
10
+ --dark-900: #1b1b1b;
11
+ --light-200: #e4e3de;
12
+ --light-400: #c4c6bb;
13
+ --primary-500: #7ea8a7;
14
+ --secondary-500: #78718e;
15
+ --surface: var(--dark-900);
16
+ --surface-raised: #262626;
17
+ --surface-sunken: #141414;
18
+ --ink: var(--light-200);
19
+ --ink-muted: var(--light-400);
20
+ --accent: var(--primary-500);
21
+ --accent-fill: var(--primary-500);
22
+ --on-accent: var(--dark-900);
23
+ --accent-soft: #7ea8a71f;
24
+ --secondary: #a49dba;
25
+ --secondary-fill: var(--secondary-500);
26
+ --on-secondary: #ffffff;
27
+ --line: #ffffff26;
28
+ --line-strong: var(--secondary-500);
29
+ --focus-ring: var(--accent);
30
+ --glass-regular-tint: #1b1b1b4d;
31
+ --glass-thick-tint: #1b1b1bf0;
32
+ --glass-solid: var(--surface-raised);
33
+ --glass-clear-tint: #e4e3de12;
34
+ --glass-sheen: #ffffff2e;
35
+ --glass-rim: #ffffffd9;
36
+ --glass-rim-low: #ffffff80;
37
+ --glass-edge: #ffffff1f;
38
+ --glass-accent-tint: #7ea8a71f;
39
+ --glass-accent-sheen: #b9d8d759;
40
+ --success: #8ab4d8;
41
+ --warning: #e3c47b;
42
+ --danger: #f19b90;
43
+ --on-danger: var(--dark-900);
44
+ --scrim: #0000008c;
45
+ --shadow-glass: inset 0 1px 1px rgba(255,255,255,0.45), inset 0 -1px 1px rgba(255,255,255,0.12), inset 0 0 20px rgba(255,255,255,0.08), 0 10px 30px -8px rgba(0,0,0,0.45);
46
+ --shadow-glow: 0 0 14px rgba(126,168,167,0.55);
47
+ --shadow-raised: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
48
+ --glass-text-shadow: 0 1px 2px rgba(0,0,0,0.35);
49
+ }
50
+
51
+ [data-theme="light"] {
52
+ color-scheme: light;
53
+ --dark-900: #1b1b1b;
54
+ --light-200: #e4e3de;
55
+ --light-400: #c4c6bb;
56
+ --primary-500: #7ea8a7;
57
+ --secondary-500: #78718e;
58
+ --surface: #f2f1ec;
59
+ --surface-raised: #faf9f6;
60
+ --surface-sunken: var(--light-200);
61
+ --ink: var(--dark-900);
62
+ --ink-muted: #55574f;
63
+ --accent: #3f6b6a;
64
+ --accent-fill: var(--primary-500);
65
+ --on-accent: var(--dark-900);
66
+ --accent-soft: #3f6b6a1f;
67
+ --secondary: #5a5374;
68
+ --secondary-fill: var(--secondary-500);
69
+ --on-secondary: #ffffff;
70
+ --line: #1b1b1b26;
71
+ --line-strong: var(--secondary-500);
72
+ --focus-ring: var(--accent);
73
+ --glass-regular-tint: #f2f1ec33;
74
+ --glass-thick-tint: #f2f1ecf0;
75
+ --glass-solid: var(--surface-raised);
76
+ --glass-clear-tint: #ffffff8c;
77
+ --glass-sheen: #ffffff66;
78
+ --glass-rim: #ffffff;
79
+ --glass-rim-low: #ffffffb3;
80
+ --glass-edge: #1b1b1b29;
81
+ --glass-accent-tint: #7ea8a71f;
82
+ --glass-accent-sheen: #b9d8d759;
83
+ --success: #2d5b86;
84
+ --warning: #765811;
85
+ --danger: #a1342a;
86
+ --on-danger: #ffffff;
87
+ --scrim: #1b1b1b59;
88
+ --shadow-glass: inset 0 1px 1px rgba(255,255,255,0.9), inset 0 -1px 1px rgba(255,255,255,0.4), inset 0 0 20px rgba(255,255,255,0.25), 0 10px 30px -8px rgba(27,27,27,0.25);
89
+ --shadow-glow: 0 0 14px rgba(63,107,106,0.35);
90
+ --shadow-raised: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
91
+ --glass-text-shadow: 0 1px 1px rgba(255,255,255,0.6);
92
+ }
93
+
94
+ :root {
95
+ --space-1: 4px;
96
+ --space-2: 8px;
97
+ --space-3: 12px;
98
+ --space-4: 16px;
99
+ --space-6: 24px;
100
+ --space-8: 32px;
101
+ --space-10: 40px;
102
+ --space-20: 80px;
103
+ --radius-sm: 2px;
104
+ --radius-md: 6px;
105
+ --radius-lg: 8px;
106
+ --radius-xl: 12px;
107
+ --radius-full: 9999px;
108
+ --radius-2xl: 24px;
109
+ --content-max: 1152px;
110
+ --sidebar-width: 64px;
111
+ --glass-blur: blur(6px) saturate(180%);
112
+ --glass-thick-blur: blur(20px) saturate(150%);
113
+ --glass-accent-blur: blur(6px) saturate(200%);
114
+ --font-sans: Raleway, "Segoe UI", system-ui, sans-serif;
115
+ --font-mono: "JetBrains Mono", ui-monospace, Consolas, monospace;
116
+ }
117
+
118
+ .hds-text-title-xl {
119
+ font-family: var(--font-sans);
120
+ font-size: 36px;
121
+ line-height: 40px;
122
+ font-weight: 700;
123
+ }
124
+
125
+ .hds-text-title-lg {
126
+ font-family: var(--font-sans);
127
+ font-size: 24px;
128
+ line-height: 32px;
129
+ font-weight: 700;
130
+ }
131
+
132
+ .hds-text-title-md {
133
+ font-family: var(--font-sans);
134
+ font-size: 20px;
135
+ line-height: 28px;
136
+ font-weight: 600;
137
+ }
138
+
139
+ .hds-text-body-lg {
140
+ font-family: var(--font-sans);
141
+ font-size: 18px;
142
+ line-height: 28px;
143
+ font-weight: 500;
144
+ }
145
+
146
+ .hds-text-body {
147
+ font-family: var(--font-sans);
148
+ font-size: 16px;
149
+ line-height: 24px;
150
+ font-weight: 400;
151
+ }
152
+
153
+ .hds-text-body-sm {
154
+ font-family: var(--font-sans);
155
+ font-size: 14px;
156
+ line-height: 20px;
157
+ font-weight: 400;
158
+ }
159
+
160
+ .hds-text-caption {
161
+ font-family: var(--font-sans);
162
+ font-size: 12px;
163
+ line-height: 16px;
164
+ font-weight: 500;
165
+ }
166
+
167
+ .hds-text-button {
168
+ font-family: var(--font-sans);
169
+ font-size: 16px;
170
+ line-height: 24px;
171
+ font-weight: 700;
172
+ }
173
+
174
+ .hds-text-eyebrow {
175
+ font-family: var(--font-sans);
176
+ font-size: 14px;
177
+ line-height: 20px;
178
+ font-weight: 700;
179
+ letter-spacing: 0.025em;
180
+ }
181
+
182
+ .hds-text-section-index {
183
+ font-family: var(--font-mono);
184
+ font-size: 20px;
185
+ line-height: 28px;
186
+ font-weight: 700;
187
+ }
188
+
189
+ .hds-text-mono-sm {
190
+ font-family: var(--font-mono);
191
+ font-size: 14px;
192
+ line-height: 20px;
193
+ font-weight: 500;
194
+ }
195
+
196
+ /* Hemerson Design System: component styles. Every color, length and shadow
197
+ comes from tokens.css; the only literals are the -webkit-backdrop-filter
198
+ values, because Safari does not resolve custom properties there. */
199
+
200
+ /* ---------- Base ---------- */
201
+
202
+ .hds-root {
203
+ font-family: var(--font-sans);
204
+ color: var(--ink);
205
+ background: var(--surface);
206
+ }
207
+
208
+ :where([class^="hds-"], [class*=" hds-"]) {
209
+ box-sizing: border-box;
210
+ }
211
+
212
+ :where(.hds-btn, .hds-input, .hds-select, .hds-checkbox-input, .hds-segmented-option,
213
+ .hds-menu-item, .hds-sidebar-item, .hds-navbar-link, .hds-scroll):focus-visible {
214
+ outline: 2px solid var(--focus-ring);
215
+ outline-offset: 2px;
216
+ }
217
+
218
+ /* Dialogs and toasts render straight into <body>, outside .hds-root */
219
+ .hds-scrim,
220
+ .hds-toast-region {
221
+ font-family: var(--font-sans);
222
+ color: var(--ink);
223
+ }
224
+
225
+ .hds-visually-hidden {
226
+ position: absolute;
227
+ width: 1px;
228
+ height: 1px;
229
+ margin: -1px;
230
+ padding: 0;
231
+ overflow: hidden;
232
+ clip: rect(0 0 0 0);
233
+ white-space: nowrap;
234
+ border: 0;
235
+ }
236
+
237
+ .hds-icon {
238
+ flex: none;
239
+ width: 1em;
240
+ height: 1em;
241
+ }
242
+
243
+ /* ---------- Glass material ----------
244
+ Modelled on Apple's Liquid Glass: a light tint so the content behind stays visible,
245
+ a light blur, a lit rim brightest at the top-left, a soft inner glow and, in Chromium,
246
+ a lens that bends the backdrop near the edges.
247
+
248
+ Layer 1: solid, always readable. Layer 2: frosted glass where backdrop-filter works.
249
+ Layer 3: the edge lens, added per element by enableGlassRefraction() (Chromium only).
250
+
251
+ Glass follows the brightness of what is behind it: over dark imagery in the light
252
+ theme, set data-theme="dark" on the glass element itself, and the reverse. */
253
+
254
+ .hds-glass {
255
+ position: relative;
256
+ isolation: isolate;
257
+ color: var(--ink);
258
+ background: var(--glass-solid);
259
+ border: 1px solid var(--line);
260
+ box-shadow: var(--shadow-raised);
261
+ }
262
+
263
+ @supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
264
+ .hds-glass {
265
+ border: 0;
266
+ background: linear-gradient(135deg, var(--glass-sheen), transparent 42%), var(--glass-regular-tint);
267
+ box-shadow: 0 0 0 0.5px var(--glass-edge), var(--shadow-glass);
268
+ text-shadow: var(--glass-text-shadow);
269
+ -webkit-backdrop-filter: blur(6px) saturate(180%);
270
+ backdrop-filter: var(--glass-blur);
271
+ }
272
+
273
+ /* The lit rim: brightest at the top-left, softer at the bottom-right */
274
+ .hds-glass::before {
275
+ content: "";
276
+ position: absolute;
277
+ inset: 0;
278
+ z-index: -1;
279
+ padding: 1.5px;
280
+ border-radius: inherit;
281
+ background: linear-gradient(135deg, var(--glass-rim), transparent 38%, transparent 62%, var(--glass-rim-low));
282
+ -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
283
+ -webkit-mask-composite: xor;
284
+ mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
285
+ pointer-events: none;
286
+ }
287
+
288
+ .hds-glass--clear {
289
+ background: linear-gradient(135deg, var(--glass-sheen), transparent 42%), var(--glass-clear-tint);
290
+ }
291
+
292
+ .hds-glass--thick {
293
+ background: linear-gradient(135deg, var(--glass-sheen), transparent 42%), var(--glass-thick-tint);
294
+ -webkit-backdrop-filter: blur(20px) saturate(150%);
295
+ backdrop-filter: var(--glass-thick-blur);
296
+ }
297
+
298
+ .hds-glass--accent {
299
+ background: linear-gradient(135deg, var(--glass-accent-sheen), transparent 60%), var(--glass-accent-tint), var(--glass-regular-tint);
300
+ box-shadow: 0 0 0 1px var(--accent), var(--shadow-glass), var(--shadow-glow);
301
+ -webkit-backdrop-filter: blur(6px) saturate(200%);
302
+ backdrop-filter: var(--glass-accent-blur);
303
+ }
304
+ }
305
+
306
+ /* Edge lens: enableGlassRefraction() sets --hds-glass-lens on each glass element */
307
+ html[data-glass-refraction] .hds-glass:not(.hds-glass--thick) {
308
+ backdrop-filter: var(--hds-glass-lens, blur(0px)) blur(4px) saturate(180%);
309
+ }
310
+
311
+ html[data-glass-refraction] .hds-glass--accent {
312
+ backdrop-filter: var(--hds-glass-lens, blur(0px)) blur(4px) saturate(200%);
313
+ }
314
+
315
+ /* Reduced transparency: the system setting, or the app's own setting */
316
+ @media (prefers-reduced-transparency: reduce) {
317
+ html .hds-glass,
318
+ html[data-glass-refraction] .hds-glass:not(.hds-glass--thick) {
319
+ border: 1px solid var(--line);
320
+ background: var(--glass-solid);
321
+ box-shadow: var(--shadow-raised);
322
+ text-shadow: none;
323
+ -webkit-backdrop-filter: none;
324
+ backdrop-filter: none;
325
+ }
326
+
327
+ html .hds-glass::before {
328
+ display: none;
329
+ }
330
+ }
331
+
332
+ html[data-transparency="reduced"] .hds-glass,
333
+ html[data-transparency="reduced"][data-glass-refraction] .hds-glass:not(.hds-glass--thick) {
334
+ border: 1px solid var(--line);
335
+ background: var(--glass-solid);
336
+ box-shadow: var(--shadow-raised);
337
+ text-shadow: none;
338
+ -webkit-backdrop-filter: none;
339
+ backdrop-filter: none;
340
+ }
341
+
342
+ html[data-transparency="reduced"] .hds-glass::before {
343
+ display: none;
344
+ }
345
+
346
+ @media (prefers-contrast: more) {
347
+ .hds-glass {
348
+ box-shadow: 0 0 0 2px currentColor, var(--shadow-glass);
349
+ }
350
+ }
351
+
352
+ /* ---------- Button ---------- */
353
+
354
+ .hds-btn {
355
+ display: inline-flex;
356
+ align-items: center;
357
+ justify-content: center;
358
+ gap: var(--space-2);
359
+ min-height: 40px;
360
+ padding: var(--space-2) var(--space-4);
361
+ border: 1px solid transparent;
362
+ border-radius: var(--radius-md);
363
+ font-family: var(--font-sans);
364
+ font-size: 16px;
365
+ line-height: 24px;
366
+ font-weight: 700;
367
+ text-transform: uppercase;
368
+ white-space: nowrap;
369
+ text-decoration: none;
370
+ cursor: pointer;
371
+ transition: opacity 150ms, background-color 150ms, color 150ms, filter 150ms;
372
+ }
373
+
374
+ .hds-btn .hds-icon {
375
+ font-size: 20px;
376
+ }
377
+
378
+ .hds-btn--sm {
379
+ min-height: 32px;
380
+ padding: var(--space-1) var(--space-3);
381
+ font-size: 14px;
382
+ line-height: 20px;
383
+ }
384
+
385
+ .hds-btn--sm .hds-icon {
386
+ font-size: 16px;
387
+ }
388
+
389
+ .hds-btn--lg {
390
+ min-height: 56px;
391
+ padding: var(--space-4);
392
+ }
393
+
394
+ .hds-btn--icon {
395
+ padding: 0;
396
+ aspect-ratio: 1;
397
+ }
398
+
399
+ .hds-btn--primary {
400
+ background: var(--accent-fill);
401
+ color: var(--on-accent);
402
+ }
403
+
404
+ .hds-btn--secondary {
405
+ background: var(--secondary-fill);
406
+ color: var(--on-secondary);
407
+ }
408
+
409
+ .hds-btn--danger {
410
+ background: var(--danger);
411
+ color: var(--on-danger);
412
+ }
413
+
414
+ .hds-btn--primary:hover,
415
+ .hds-btn--secondary:hover,
416
+ .hds-btn--danger:hover {
417
+ opacity: 0.8;
418
+ }
419
+
420
+ .hds-btn--ghost {
421
+ background: transparent;
422
+ color: var(--ink);
423
+ }
424
+
425
+ .hds-btn--ghost:hover {
426
+ background: var(--accent-soft);
427
+ color: var(--accent);
428
+ }
429
+
430
+ .hds-btn--glass {
431
+ border-radius: var(--radius-full);
432
+ }
433
+
434
+ .hds-btn--glass:hover {
435
+ filter: brightness(1.15);
436
+ }
437
+
438
+ .hds-btn:disabled,
439
+ .hds-btn[aria-disabled="true"] {
440
+ opacity: 0.5;
441
+ cursor: not-allowed;
442
+ }
443
+
444
+ .hds-btn[aria-busy="true"] {
445
+ cursor: progress;
446
+ }
447
+
448
+ /* ---------- Loading ---------- */
449
+
450
+ .hds-loading {
451
+ display: inline-flex;
452
+ align-items: center;
453
+ gap: var(--space-2);
454
+ color: var(--accent);
455
+ }
456
+
457
+ .hds-loading .hds-icon,
458
+ .hds-spin {
459
+ animation: hds-spin 0.8s linear infinite;
460
+ }
461
+
462
+ .hds-loading--sm .hds-icon { font-size: 16px; }
463
+ .hds-loading--md .hds-icon { font-size: 24px; }
464
+ .hds-loading--lg .hds-icon { font-size: 32px; }
465
+
466
+ @keyframes hds-spin {
467
+ to { transform: rotate(360deg); }
468
+ }
469
+
470
+ /* ---------- NavBar ---------- */
471
+
472
+ .hds-navbar {
473
+ position: sticky;
474
+ top: var(--space-4);
475
+ z-index: 20;
476
+ display: flex;
477
+ align-items: center;
478
+ gap: var(--space-4);
479
+ width: 100%;
480
+ max-width: var(--content-max);
481
+ min-height: 56px;
482
+ margin-inline: auto;
483
+ padding: var(--space-2) var(--space-2) var(--space-2) var(--space-6);
484
+ border-radius: var(--radius-full);
485
+ }
486
+
487
+ .hds-navbar-title {
488
+ margin: 0;
489
+ font-size: 20px;
490
+ line-height: 28px;
491
+ font-weight: 600;
492
+ white-space: nowrap;
493
+ }
494
+
495
+ .hds-navbar-nav {
496
+ display: flex;
497
+ flex: 1;
498
+ gap: var(--space-1);
499
+ min-width: 0;
500
+ overflow-x: auto;
501
+ }
502
+
503
+ .hds-navbar-actions {
504
+ display: flex;
505
+ align-items: center;
506
+ gap: var(--space-2);
507
+ margin-left: auto;
508
+ }
509
+
510
+ .hds-navbar-link {
511
+ display: inline-flex;
512
+ align-items: center;
513
+ min-height: 40px;
514
+ padding: 0 var(--space-4);
515
+ border-radius: var(--radius-full);
516
+ color: var(--ink);
517
+ font-size: 14px;
518
+ line-height: 20px;
519
+ font-weight: 600;
520
+ text-decoration: none;
521
+ white-space: nowrap;
522
+ transition: background-color 150ms, color 150ms;
523
+ }
524
+
525
+ .hds-navbar-link:hover {
526
+ color: var(--accent);
527
+ }
528
+
529
+ .hds-navbar-link[aria-current="page"] {
530
+ background: var(--accent-soft);
531
+ color: var(--accent);
532
+ }
533
+
534
+ /* ---------- Sidebar ---------- */
535
+
536
+ .hds-sidebar {
537
+ display: flex;
538
+ flex-direction: column;
539
+ align-items: center;
540
+ gap: var(--space-2);
541
+ width: var(--sidebar-width);
542
+ height: 100%;
543
+ padding: var(--space-3) 0;
544
+ border-width: 0 1px 0 0;
545
+ }
546
+
547
+ .hds-sidebar--floating {
548
+ height: auto;
549
+ border-width: 1px;
550
+ border-radius: var(--radius-full);
551
+ }
552
+
553
+ .hds-sidebar-items {
554
+ display: flex;
555
+ flex-direction: column;
556
+ gap: var(--space-2);
557
+ margin: 0;
558
+ padding: 0;
559
+ list-style: none;
560
+ }
561
+
562
+ .hds-sidebar-footer {
563
+ margin-top: auto;
564
+ }
565
+
566
+ .hds-sidebar-item {
567
+ display: grid;
568
+ place-items: center;
569
+ width: 40px;
570
+ height: 40px;
571
+ border: 0;
572
+ border-radius: var(--radius-full);
573
+ background: transparent;
574
+ color: var(--ink);
575
+ font-size: 20px;
576
+ cursor: pointer;
577
+ text-decoration: none;
578
+ transition: background-color 150ms, color 150ms;
579
+ }
580
+
581
+ .hds-sidebar-item:hover {
582
+ color: var(--accent);
583
+ }
584
+
585
+ .hds-sidebar-item[aria-current="page"] {
586
+ background: var(--accent-soft);
587
+ color: var(--accent);
588
+ }
589
+
590
+ /* ---------- SegmentedControl ---------- */
591
+
592
+ .hds-segmented {
593
+ display: inline-flex;
594
+ position: relative;
595
+ padding: var(--space-1);
596
+ border-radius: var(--radius-full);
597
+ }
598
+
599
+ /* The thumb looks like accent glass but adds no second backdrop-filter:
600
+ glass is never stacked on glass. */
601
+ .hds-segmented-thumb {
602
+ position: absolute;
603
+ top: var(--space-1);
604
+ bottom: var(--space-1);
605
+ left: var(--space-1);
606
+ border: 1px solid var(--accent);
607
+ border-radius: var(--radius-full);
608
+ background: linear-gradient(135deg, var(--glass-accent-sheen), transparent 60%), var(--glass-accent-tint);
609
+ box-shadow: var(--shadow-glow);
610
+ transition: transform 300ms ease-out;
611
+ pointer-events: none;
612
+ }
613
+
614
+ .hds-segmented-option {
615
+ position: relative;
616
+ z-index: 1;
617
+ display: inline-flex;
618
+ align-items: center;
619
+ justify-content: center;
620
+ gap: var(--space-1);
621
+ min-height: 32px;
622
+ padding: 0 var(--space-3);
623
+ border: 0;
624
+ border-radius: var(--radius-full);
625
+ background: transparent;
626
+ color: var(--ink);
627
+ font-family: var(--font-sans);
628
+ font-size: 14px;
629
+ line-height: 20px;
630
+ font-weight: 600;
631
+ cursor: pointer;
632
+ opacity: 0.75;
633
+ transition: opacity 300ms ease-out;
634
+ }
635
+
636
+ .hds-segmented-option:hover,
637
+ .hds-segmented-option[aria-checked="true"] {
638
+ opacity: 1;
639
+ }
640
+
641
+ /* ---------- FloatingButton ---------- */
642
+
643
+ .hds-fab {
644
+ position: fixed;
645
+ z-index: 10;
646
+ display: grid;
647
+ place-items: center;
648
+ width: 56px;
649
+ height: 56px;
650
+ padding: 0;
651
+ border-radius: var(--radius-full);
652
+ color: var(--ink);
653
+ font-size: 24px;
654
+ cursor: pointer;
655
+ transition: filter 150ms;
656
+ }
657
+
658
+ .hds-fab:hover {
659
+ filter: brightness(1.25);
660
+ }
661
+
662
+ .hds-fab--bottom-right {
663
+ right: calc(var(--space-6) + env(safe-area-inset-right, 0px));
664
+ bottom: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
665
+ }
666
+
667
+ .hds-fab--bottom-left {
668
+ left: calc(var(--space-6) + env(safe-area-inset-left, 0px));
669
+ bottom: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
670
+ }
671
+
672
+ .hds-fab--top-right {
673
+ right: calc(var(--space-6) + env(safe-area-inset-right, 0px));
674
+ top: calc(var(--space-6) + env(safe-area-inset-top, 0px));
675
+ }
676
+
677
+ .hds-fab--top-left {
678
+ left: calc(var(--space-6) + env(safe-area-inset-left, 0px));
679
+ top: calc(var(--space-6) + env(safe-area-inset-top, 0px));
680
+ }
681
+
682
+ /* ---------- Menu ---------- */
683
+
684
+ .hds-menu {
685
+ position: relative;
686
+ display: inline-block;
687
+ }
688
+
689
+ .hds-menu-panel {
690
+ position: absolute;
691
+ top: calc(100% + var(--space-2));
692
+ z-index: 30;
693
+ min-width: 176px;
694
+ padding: var(--space-1);
695
+ border-radius: var(--radius-lg);
696
+ }
697
+
698
+ .hds-menu-panel--start { left: 0; }
699
+ .hds-menu-panel--end { right: 0; }
700
+
701
+ .hds-menu-item {
702
+ display: flex;
703
+ align-items: center;
704
+ gap: var(--space-2);
705
+ width: 100%;
706
+ min-height: 36px;
707
+ padding: var(--space-2) var(--space-3);
708
+ border: 0;
709
+ border-radius: var(--space-1);
710
+ background: transparent;
711
+ color: var(--ink);
712
+ font-family: var(--font-sans);
713
+ font-size: 14px;
714
+ line-height: 20px;
715
+ font-weight: 500;
716
+ text-align: left;
717
+ cursor: pointer;
718
+ }
719
+
720
+ .hds-menu-item .hds-icon {
721
+ font-size: 16px;
722
+ }
723
+
724
+ .hds-menu-item:hover,
725
+ .hds-menu-item:focus-visible {
726
+ background: var(--accent-soft);
727
+ }
728
+
729
+ .hds-menu-item--danger {
730
+ color: var(--danger);
731
+ }
732
+
733
+ .hds-menu-separator {
734
+ height: 1px;
735
+ margin: var(--space-1) var(--space-2);
736
+ background: var(--line);
737
+ }
738
+
739
+ /* ---------- Dialog ---------- */
740
+
741
+ .hds-scrim {
742
+ position: fixed;
743
+ inset: 0;
744
+ z-index: 50;
745
+ display: grid;
746
+ place-items: center;
747
+ padding: var(--space-4);
748
+ background: var(--scrim);
749
+ }
750
+
751
+ .hds-dialog {
752
+ display: flex;
753
+ flex-direction: column;
754
+ gap: var(--space-4);
755
+ width: 100%;
756
+ max-width: 560px;
757
+ max-height: calc(100% - var(--space-8));
758
+ overflow: auto;
759
+ padding: var(--space-6);
760
+ border-radius: var(--radius-2xl);
761
+ }
762
+
763
+ .hds-dialog-header {
764
+ display: flex;
765
+ align-items: flex-start;
766
+ justify-content: space-between;
767
+ gap: var(--space-4);
768
+ }
769
+
770
+ .hds-dialog-title {
771
+ margin: 0;
772
+ font-size: 20px;
773
+ line-height: 28px;
774
+ font-weight: 600;
775
+ }
776
+
777
+ .hds-dialog-description {
778
+ margin: var(--space-1) 0 0;
779
+ color: var(--ink-muted);
780
+ font-size: 14px;
781
+ line-height: 20px;
782
+ }
783
+
784
+ .hds-dialog-footer {
785
+ display: flex;
786
+ flex-wrap: wrap;
787
+ justify-content: flex-end;
788
+ gap: var(--space-2);
789
+ }
790
+
791
+ /* ---------- Toast ---------- */
792
+
793
+ .hds-toast-region {
794
+ position: fixed;
795
+ left: 50%;
796
+ bottom: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
797
+ z-index: 60;
798
+ display: flex;
799
+ flex-direction: column;
800
+ gap: var(--space-2);
801
+ width: min(420px, calc(100% - var(--space-8)));
802
+ transform: translateX(-50%);
803
+ }
804
+
805
+ .hds-toast {
806
+ display: flex;
807
+ align-items: flex-start;
808
+ gap: var(--space-3);
809
+ padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
810
+ border-radius: var(--radius-2xl);
811
+ animation: hds-toast-in 300ms ease-out;
812
+ }
813
+
814
+ .hds-toast > .hds-icon {
815
+ margin-top: 2px;
816
+ font-size: 20px;
817
+ }
818
+
819
+ .hds-toast--success > .hds-icon { color: var(--success); }
820
+ .hds-toast--warning > .hds-icon { color: var(--warning); }
821
+ .hds-toast--danger > .hds-icon { color: var(--danger); }
822
+ .hds-toast--neutral > .hds-icon { color: var(--accent); }
823
+
824
+ .hds-toast-body {
825
+ flex: 1;
826
+ min-width: 0;
827
+ font-size: 14px;
828
+ line-height: 20px;
829
+ }
830
+
831
+ .hds-toast-title {
832
+ margin: 0;
833
+ font-weight: 700;
834
+ }
835
+
836
+ .hds-toast-description {
837
+ margin: 0;
838
+ }
839
+
840
+ @keyframes hds-toast-in {
841
+ from { opacity: 0; transform: translateY(var(--space-2)); }
842
+ }
843
+
844
+ /* ---------- Forms ---------- */
845
+
846
+ .hds-field {
847
+ display: flex;
848
+ flex-direction: column;
849
+ gap: var(--space-1);
850
+ min-width: 0;
851
+ }
852
+
853
+ .hds-label {
854
+ color: var(--ink);
855
+ font-size: 14px;
856
+ line-height: 20px;
857
+ font-weight: 600;
858
+ }
859
+
860
+ .hds-hint {
861
+ margin: 0;
862
+ color: var(--ink-muted);
863
+ font-size: 14px;
864
+ line-height: 20px;
865
+ }
866
+
867
+ .hds-error {
868
+ display: flex;
869
+ align-items: center;
870
+ gap: var(--space-1);
871
+ margin: 0;
872
+ color: var(--danger);
873
+ font-size: 14px;
874
+ line-height: 20px;
875
+ font-weight: 600;
876
+ }
877
+
878
+ .hds-input,
879
+ .hds-select {
880
+ width: 100%;
881
+ min-height: 40px;
882
+ padding: var(--space-2) var(--space-3);
883
+ border: 1px solid var(--line-strong);
884
+ border-radius: var(--radius-md);
885
+ background: var(--surface-sunken);
886
+ color: var(--ink);
887
+ font-family: var(--font-sans);
888
+ font-size: 16px;
889
+ line-height: 24px;
890
+ transition: border-color 150ms;
891
+ }
892
+
893
+ .hds-input::placeholder {
894
+ color: var(--ink-muted);
895
+ opacity: 1;
896
+ }
897
+
898
+ .hds-input:hover,
899
+ .hds-select:hover {
900
+ border-color: var(--accent);
901
+ }
902
+
903
+ .hds-input[aria-invalid="true"],
904
+ .hds-select[aria-invalid="true"] {
905
+ border-color: var(--danger);
906
+ }
907
+
908
+ .hds-input:disabled,
909
+ .hds-select:disabled {
910
+ opacity: 0.5;
911
+ cursor: not-allowed;
912
+ }
913
+
914
+ .hds-input--numeric {
915
+ font-family: var(--font-mono);
916
+ font-variant-numeric: tabular-nums;
917
+ }
918
+
919
+ .hds-select-wrap {
920
+ position: relative;
921
+ }
922
+
923
+ .hds-select {
924
+ -webkit-appearance: none;
925
+ appearance: none;
926
+ padding-right: var(--space-10);
927
+ cursor: pointer;
928
+ }
929
+
930
+ .hds-select-wrap > .hds-icon {
931
+ position: absolute;
932
+ top: 50%;
933
+ right: var(--space-3);
934
+ font-size: 16px;
935
+ color: var(--ink-muted);
936
+ transform: translateY(-50%);
937
+ pointer-events: none;
938
+ }
939
+
940
+ .hds-checkbox {
941
+ display: inline-flex;
942
+ align-items: flex-start;
943
+ gap: var(--space-2);
944
+ color: var(--ink);
945
+ font-size: 16px;
946
+ line-height: 24px;
947
+ cursor: pointer;
948
+ }
949
+
950
+ .hds-checkbox-control {
951
+ position: relative;
952
+ display: inline-grid;
953
+ flex: none;
954
+ width: 20px;
955
+ height: 20px;
956
+ margin-top: 2px;
957
+ }
958
+
959
+ .hds-checkbox-input {
960
+ position: absolute;
961
+ inset: 0;
962
+ width: 100%;
963
+ height: 100%;
964
+ margin: 0;
965
+ opacity: 0;
966
+ cursor: pointer;
967
+ }
968
+
969
+ .hds-checkbox-box {
970
+ display: grid;
971
+ place-items: center;
972
+ border: 1.5px solid var(--line-strong);
973
+ border-radius: var(--radius-sm);
974
+ background: var(--surface-sunken);
975
+ color: var(--on-accent);
976
+ font-size: 14px;
977
+ pointer-events: none;
978
+ transition: background-color 150ms, border-color 150ms;
979
+ }
980
+
981
+ .hds-checkbox-box .hds-icon {
982
+ opacity: 0;
983
+ }
984
+
985
+ .hds-checkbox-input:checked + .hds-checkbox-box {
986
+ border-color: var(--accent-fill);
987
+ background: var(--accent-fill);
988
+ }
989
+
990
+ .hds-checkbox-input:checked + .hds-checkbox-box .hds-icon {
991
+ opacity: 1;
992
+ }
993
+
994
+ .hds-checkbox-input:focus-visible + .hds-checkbox-box {
995
+ outline: 2px solid var(--focus-ring);
996
+ outline-offset: 2px;
997
+ }
998
+
999
+ .hds-checkbox-input:disabled + .hds-checkbox-box {
1000
+ opacity: 0.5;
1001
+ }
1002
+
1003
+ .hds-checkbox-text {
1004
+ display: flex;
1005
+ flex-direction: column;
1006
+ }
1007
+
1008
+ /* ---------- Card ---------- */
1009
+
1010
+ .hds-card {
1011
+ display: flex;
1012
+ flex-direction: column;
1013
+ overflow: hidden;
1014
+ border: 1px solid var(--line);
1015
+ border-radius: var(--radius-lg);
1016
+ background: var(--surface-raised);
1017
+ color: var(--ink);
1018
+ box-shadow: var(--shadow-raised);
1019
+ }
1020
+
1021
+ .hds-card--interactive {
1022
+ transition: transform 200ms ease-out;
1023
+ }
1024
+
1025
+ .hds-card--interactive:hover {
1026
+ transform: scale(1.02);
1027
+ }
1028
+
1029
+ .hds-card-media {
1030
+ display: block;
1031
+ width: 100%;
1032
+ aspect-ratio: 16 / 9;
1033
+ object-fit: cover;
1034
+ }
1035
+
1036
+ .hds-card-body {
1037
+ display: flex;
1038
+ flex-direction: column;
1039
+ gap: var(--space-2);
1040
+ padding: var(--space-6);
1041
+ }
1042
+
1043
+ .hds-card-eyebrow {
1044
+ margin: 0;
1045
+ color: var(--secondary);
1046
+ font-size: 14px;
1047
+ line-height: 20px;
1048
+ font-weight: 700;
1049
+ letter-spacing: 0.025em;
1050
+ text-transform: uppercase;
1051
+ }
1052
+
1053
+ .hds-card-title {
1054
+ margin: 0;
1055
+ font-size: 20px;
1056
+ line-height: 28px;
1057
+ font-weight: 600;
1058
+ }
1059
+
1060
+ .hds-card-text {
1061
+ color: var(--ink-muted);
1062
+ font-size: 14px;
1063
+ line-height: 20px;
1064
+ }
1065
+
1066
+ .hds-card-footer {
1067
+ display: flex;
1068
+ flex-wrap: wrap;
1069
+ gap: var(--space-3);
1070
+ padding: 0 var(--space-6) var(--space-6);
1071
+ }
1072
+
1073
+ /* ---------- Badge ---------- */
1074
+
1075
+ .hds-badge {
1076
+ display: inline-flex;
1077
+ align-items: center;
1078
+ gap: var(--space-1);
1079
+ padding: 2px var(--space-2);
1080
+ border-radius: var(--radius-full);
1081
+ color: var(--ink);
1082
+ font-size: 12px;
1083
+ line-height: 16px;
1084
+ font-weight: 600;
1085
+ white-space: nowrap;
1086
+ }
1087
+
1088
+ .hds-badge .hds-icon {
1089
+ font-size: 14px;
1090
+ }
1091
+
1092
+ .hds-badge--neutral {
1093
+ background: color-mix(in srgb, var(--ink) 8%, transparent);
1094
+ }
1095
+
1096
+ .hds-badge--neutral .hds-icon { color: var(--ink-muted); }
1097
+ .hds-badge--accent { background: color-mix(in srgb, var(--accent) 14%, transparent); }
1098
+ .hds-badge--accent .hds-icon { color: var(--accent); }
1099
+ .hds-badge--success { background: color-mix(in srgb, var(--success) 14%, transparent); }
1100
+ .hds-badge--success .hds-icon { color: var(--success); }
1101
+ .hds-badge--warning { background: color-mix(in srgb, var(--warning) 14%, transparent); }
1102
+ .hds-badge--warning .hds-icon { color: var(--warning); }
1103
+ .hds-badge--danger { background: color-mix(in srgb, var(--danger) 14%, transparent); }
1104
+ .hds-badge--danger .hds-icon { color: var(--danger); }
1105
+
1106
+ /* ---------- Table ---------- */
1107
+
1108
+ .hds-table-wrap {
1109
+ overflow-x: auto;
1110
+ border: 1px solid var(--line);
1111
+ border-radius: var(--radius-lg);
1112
+ background: var(--surface-raised);
1113
+ }
1114
+
1115
+ .hds-table {
1116
+ width: 100%;
1117
+ border-collapse: separate;
1118
+ border-spacing: 0;
1119
+ color: var(--ink);
1120
+ font-size: 14px;
1121
+ line-height: 20px;
1122
+ }
1123
+
1124
+ .hds-table caption {
1125
+ padding: var(--space-3) var(--space-4);
1126
+ color: var(--ink-muted);
1127
+ text-align: left;
1128
+ }
1129
+
1130
+ .hds-table th {
1131
+ position: sticky;
1132
+ top: 0;
1133
+ padding: var(--space-3) var(--space-4);
1134
+ background: var(--surface-sunken);
1135
+ color: var(--ink-muted);
1136
+ font-weight: 600;
1137
+ text-align: left;
1138
+ white-space: nowrap;
1139
+ }
1140
+
1141
+ .hds-table td {
1142
+ padding: var(--space-3) var(--space-4);
1143
+ border-top: 1px solid var(--line);
1144
+ vertical-align: middle;
1145
+ }
1146
+
1147
+ .hds-table tbody tr {
1148
+ transition: background-color 150ms;
1149
+ }
1150
+
1151
+ .hds-table tbody tr:hover {
1152
+ background: var(--accent-soft);
1153
+ }
1154
+
1155
+ .hds-table .hds-cell--numeric {
1156
+ font-family: var(--font-mono);
1157
+ font-weight: 500;
1158
+ font-variant-numeric: tabular-nums;
1159
+ text-align: right;
1160
+ white-space: nowrap;
1161
+ }
1162
+
1163
+ .hds-table th.hds-cell--numeric {
1164
+ font-family: var(--font-sans);
1165
+ font-weight: 600;
1166
+ }
1167
+
1168
+ .hds-table .hds-cell--center {
1169
+ text-align: center;
1170
+ }
1171
+
1172
+ .hds-table-empty {
1173
+ padding: var(--space-8) var(--space-4);
1174
+ color: var(--ink-muted);
1175
+ text-align: center;
1176
+ }
1177
+
1178
+ /* ---------- Layout and typography ---------- */
1179
+
1180
+ .hds-container {
1181
+ width: 100%;
1182
+ max-width: var(--content-max);
1183
+ margin-inline: auto;
1184
+ padding: var(--space-20) var(--space-4);
1185
+ }
1186
+
1187
+ @media (min-width: 768px) {
1188
+ .hds-container--with-sidebar {
1189
+ padding-left: calc(var(--sidebar-width) + var(--space-4));
1190
+ }
1191
+ }
1192
+
1193
+ .hds-section-title {
1194
+ display: flex;
1195
+ align-items: center;
1196
+ gap: var(--space-3);
1197
+ margin: 0;
1198
+ color: var(--ink);
1199
+ font-size: 36px;
1200
+ line-height: 40px;
1201
+ font-weight: 700;
1202
+ text-wrap: balance;
1203
+ }
1204
+
1205
+ .hds-section-index {
1206
+ color: color-mix(in srgb, var(--accent) 30%, transparent);
1207
+ font-family: var(--font-mono);
1208
+ font-size: 20px;
1209
+ line-height: 28px;
1210
+ font-weight: 700;
1211
+ filter: drop-shadow(0 0 10px var(--accent));
1212
+ }
1213
+
1214
+ .hds-separator {
1215
+ flex: none;
1216
+ background: var(--line-strong);
1217
+ }
1218
+
1219
+ .hds-separator--horizontal {
1220
+ width: 100%;
1221
+ height: 1px;
1222
+ }
1223
+
1224
+ .hds-separator--vertical {
1225
+ width: 1px;
1226
+ align-self: stretch;
1227
+ }
1228
+
1229
+ .hds-scroll {
1230
+ overflow: auto;
1231
+ scrollbar-width: thin;
1232
+ scrollbar-color: var(--secondary-500) transparent;
1233
+ }
1234
+
1235
+ .hds-scroll::-webkit-scrollbar {
1236
+ width: 10px;
1237
+ height: 10px;
1238
+ }
1239
+
1240
+ .hds-scroll::-webkit-scrollbar-track {
1241
+ background: transparent;
1242
+ }
1243
+
1244
+ .hds-scroll::-webkit-scrollbar-thumb {
1245
+ border: 2px solid var(--surface);
1246
+ border-radius: var(--radius-full);
1247
+ background-color: var(--secondary-500);
1248
+ }
1249
+
1250
+ .hds-scroll::-webkit-scrollbar-thumb:hover {
1251
+ background-color: var(--primary-500);
1252
+ }
1253
+
1254
+ .hds-avatar {
1255
+ position: relative;
1256
+ display: inline-block;
1257
+ flex: none;
1258
+ isolation: isolate;
1259
+ }
1260
+
1261
+ .hds-avatar-glow {
1262
+ position: absolute;
1263
+ inset: 0;
1264
+ z-index: -1;
1265
+ border-radius: var(--radius-full);
1266
+ background: var(--accent-fill);
1267
+ opacity: 0.7;
1268
+ filter: blur(24px);
1269
+ }
1270
+
1271
+ .hds-avatar-image {
1272
+ display: block;
1273
+ width: 100%;
1274
+ height: 100%;
1275
+ border: 4px solid var(--accent-fill);
1276
+ border-radius: var(--radius-full);
1277
+ object-fit: cover;
1278
+ }
1279
+
1280
+ /* ---------- Motion preferences ---------- */
1281
+
1282
+ @media (prefers-reduced-motion: reduce) {
1283
+ .hds-card--interactive:hover {
1284
+ transform: none;
1285
+ }
1286
+
1287
+ .hds-segmented-thumb,
1288
+ .hds-toast {
1289
+ transition: none;
1290
+ animation: none;
1291
+ }
1292
+
1293
+ .hds-loading .hds-icon,
1294
+ .hds-spin {
1295
+ animation-duration: 2.4s;
1296
+ }
1297
+ }