opui-css 3.3.2 → 3.3.4

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 (78) hide show
  1. package/LICENSE +21 -21
  2. package/dist/op.css +52 -52
  3. package/dist/theme-one/components.css +3869 -0
  4. package/dist/{theme-one.css → theme-one/theme-one.css} +4404 -4404
  5. package/dist/theme-two/components.css +3591 -0
  6. package/dist/{theme-two.css → theme-two/theme-two.css} +4121 -4121
  7. package/package.json +16 -12
  8. package/src/core/normalize.css +196 -196
  9. package/src/core/utils.css +60 -60
  10. package/src/open-props.css +10 -10
  11. package/src/themes/theme-one/components/accordion.css +172 -172
  12. package/src/themes/theme-one/components/alert.css +85 -85
  13. package/src/themes/theme-one/components/avatar.css +68 -68
  14. package/src/themes/theme-one/components/badge.css +101 -101
  15. package/src/themes/theme-one/components/button-group.css +69 -69
  16. package/src/themes/theme-one/components/button.css +281 -281
  17. package/src/themes/theme-one/components/card.css +82 -82
  18. package/src/themes/theme-one/components/checkbox-radio.css +123 -123
  19. package/src/themes/theme-one/components/chip.css +135 -135
  20. package/src/themes/theme-one/components/definition-list.css +68 -68
  21. package/src/themes/theme-one/components/dialog.css +59 -59
  22. package/src/themes/theme-one/components/divider.css +7 -7
  23. package/src/themes/theme-one/components/field-group.css +83 -83
  24. package/src/themes/theme-one/components/field.css +494 -494
  25. package/src/themes/theme-one/components/icon-button.css +40 -40
  26. package/src/themes/theme-one/components/link.css +21 -21
  27. package/src/themes/theme-one/components/list.css +318 -318
  28. package/src/themes/theme-one/components/progress.css +83 -83
  29. package/src/themes/theme-one/components/range.css +121 -121
  30. package/src/themes/theme-one/components/rich-text.css +210 -210
  31. package/src/themes/theme-one/components/select.css +163 -163
  32. package/src/themes/theme-one/components/snackbar.css +148 -148
  33. package/src/themes/theme-one/components/spinner.css +38 -38
  34. package/src/themes/theme-one/components/switch.css +225 -225
  35. package/src/themes/theme-one/components/tab-buttons.css +120 -120
  36. package/src/themes/theme-one/components/table.css +92 -92
  37. package/src/themes/theme-one/components/text-field.css +57 -57
  38. package/src/themes/theme-one/components/textarea.css +25 -25
  39. package/src/themes/theme-one/components/toggle-button-group.css +135 -135
  40. package/src/themes/theme-one/components/tooltip.css +94 -94
  41. package/src/themes/theme-one/components/typography.css +209 -209
  42. package/src/themes/theme-one/components.css +37 -37
  43. package/src/themes/theme-one/imports.css +16 -16
  44. package/src/themes/theme-one/theme.css +163 -163
  45. package/src/themes/theme-two/components/accordion.css +172 -172
  46. package/src/themes/theme-two/components/alert.css +85 -85
  47. package/src/themes/theme-two/components/avatar.css +68 -68
  48. package/src/themes/theme-two/components/badge.css +101 -101
  49. package/src/themes/theme-two/components/button-group.css +50 -50
  50. package/src/themes/theme-two/components/button.css +229 -229
  51. package/src/themes/theme-two/components/card.css +82 -82
  52. package/src/themes/theme-two/components/checkbox-radio.css +123 -123
  53. package/src/themes/theme-two/components/chip.css +135 -135
  54. package/src/themes/theme-two/components/definition-list.css +68 -68
  55. package/src/themes/theme-two/components/dialog.css +59 -59
  56. package/src/themes/theme-two/components/divider.css +7 -7
  57. package/src/themes/theme-two/components/field-group.css +83 -83
  58. package/src/themes/theme-two/components/field.css +281 -281
  59. package/src/themes/theme-two/components/icon-button.css +40 -40
  60. package/src/themes/theme-two/components/link.css +21 -21
  61. package/src/themes/theme-two/components/list.css +318 -318
  62. package/src/themes/theme-two/components/progress.css +83 -83
  63. package/src/themes/theme-two/components/range.css +121 -121
  64. package/src/themes/theme-two/components/rich-text.css +210 -210
  65. package/src/themes/theme-two/components/select.css +162 -162
  66. package/src/themes/theme-two/components/snackbar.css +148 -148
  67. package/src/themes/theme-two/components/spinner.css +38 -38
  68. package/src/themes/theme-two/components/switch.css +225 -225
  69. package/src/themes/theme-two/components/tab-buttons.css +120 -120
  70. package/src/themes/theme-two/components/table.css +99 -99
  71. package/src/themes/theme-two/components/text-field.css +57 -57
  72. package/src/themes/theme-two/components/textarea.css +25 -25
  73. package/src/themes/theme-two/components/toggle-button-group.css +135 -135
  74. package/src/themes/theme-two/components/tooltip.css +94 -94
  75. package/src/themes/theme-two/components/typography.css +209 -209
  76. package/src/themes/theme-two/components.css +37 -37
  77. package/src/themes/theme-two/imports.css +16 -16
  78. package/src/themes/theme-two/theme.css +158 -158
@@ -0,0 +1,3591 @@
1
+ /*
2
+ * Components are divided into two categories - if they are stand-alone (root) or if they are built on top of others (extended).
3
+ */
4
+
5
+ /*** Root components (no dependencies) */
6
+
7
+ @layer components.root {
8
+ :where(.button) {
9
+ --_bg-color: transparent;
10
+ --_border-color: transparent;
11
+ --_border-radius: var(--button-border-radius);
12
+ --_font-size: initial;
13
+ --_min-height: 2.375rem;
14
+ --_text-color: var(--primary);
15
+
16
+ -webkit-tap-highlight-color: transparent;
17
+ -webkit-touch-callout: none;
18
+ align-items: center;
19
+ background: var(--_bg-color) var(--ripple, none);
20
+ border-radius: var(--_border-radius);
21
+ border: var(--border-size-1) solid var(--_border-color);
22
+ color: var(--_text-color);
23
+ display: inline-flex;
24
+ font-size: var(--_font-size);
25
+ font-weight: 700;
26
+ gap: var(--size-2);
27
+ justify-content: center;
28
+ min-block-size: var(--_min-height);
29
+ padding-block: 0.5ex;
30
+ padding-inline: 1.5ex;
31
+ text-align: center;
32
+ text-decoration: none;
33
+
34
+ user-select: none;
35
+
36
+ &:where([disabled]) {
37
+ cursor: not-allowed;
38
+ opacity: 0.64;
39
+ }
40
+
41
+ @media (prefers-reduced-motion: no-preference) {
42
+ transition:
43
+ background-color 0.2s var(--ease-out-3),
44
+ box-shadow 0.2s var(--ease-out-3),
45
+ border-color 0.2s var(--ease-out-3),
46
+ color 0.2s var(--ease-out-3),
47
+ outline-offset 0.05s var(--ease-1);
48
+
49
+ /* Ripple effect */
50
+ background-position: center;
51
+
52
+ &:where(:not([disabled])) {
53
+ &:where(:not(:active):hover) {
54
+ --ripple: radial-gradient(circle, transparent 1%, var(--_bg-color) 1%)
55
+ center/15000%;
56
+
57
+ transition: background var(--button-ripple-duration);
58
+ }
59
+
60
+ &:where(:hover:active) {
61
+ background-size: var(--button-ripple-size);
62
+ transition: background 0s;
63
+ }
64
+ }
65
+ }
66
+
67
+ /* Element states */
68
+ &:where(:not([disabled])) {
69
+ &:where(:not(:active):hover) {
70
+ --_bg-color: light-dark(
71
+ oklch(from var(--primary) l 0.01 h / 20%),
72
+ oklch(from var(--primary) l 0.01 h / 40%)
73
+ );
74
+ }
75
+
76
+ &:where(:hover:active) {
77
+ --_bg-color: light-dark(
78
+ oklch(from var(--primary) l 0.06 h / 30%),
79
+ oklch(from var(--primary) l 0.06 h / 40%)
80
+ );
81
+ }
82
+ }
83
+
84
+ /* Disabled */
85
+ &:where([disabled]) {
86
+ --_text-color: color-mix(
87
+ in oklch,
88
+ var(--text-color-2) 50%,
89
+ var(--surface-default)
90
+ );
91
+ }
92
+
93
+ /* Icon */
94
+ &:where(:has(svg), &.icon-only) {
95
+ gap: 1ex;
96
+
97
+ svg {
98
+ max-block-size: 0.7lh;
99
+ color: currentColor;
100
+ }
101
+ }
102
+
103
+ /* Keyboard input */
104
+ :is(kbd) {
105
+ background-color: inherit;
106
+ border-color: currentColor;
107
+ color: inherit;
108
+ font-size: 0.85em;
109
+ line-height: 1.2;
110
+ }
111
+
112
+ /* Sizes */
113
+ &.small {
114
+ --_min-height: 1.875rem;
115
+ padding-block: 0;
116
+ padding-inline: 1ex;
117
+ }
118
+
119
+ &.large {
120
+ --_min-height: 2.875rem;
121
+ padding-inline: 4ex;
122
+ }
123
+
124
+ /* Variants */
125
+ &.outlined {
126
+ --_bg-color: var(--surface-default);
127
+ --_border-color: var(--color-8);
128
+ --_text-color: var(--color-8);
129
+
130
+ &:where(:not([disabled])) {
131
+ &:where(:not(:active):hover) {
132
+ --_bg-color: var(--color-10);
133
+ --_border-color: var(--color-10);
134
+ --_text-color: var(--color-1);
135
+ }
136
+
137
+ &:where(:active) {
138
+ --_bg-color: var(--color-9);
139
+ --_border-color: var(--color-9);
140
+ --_text-color: var(--color-1);
141
+ }
142
+ }
143
+
144
+ &:where([disabled]) {
145
+ --_bg-color: var(--surface-default);
146
+ --_border-color: color-mix(
147
+ in oklch,
148
+ var(--text-color-2) 20%,
149
+ var(--surface-default)
150
+ );
151
+ --_text-color: color-mix(
152
+ in oklch,
153
+ var(--text-color-2) 40%,
154
+ var(--surface-default)
155
+ );
156
+ }
157
+ }
158
+ &.tonal {
159
+ --_bg-color: var(--color-6);
160
+ --_text-color: var(--color-16);
161
+
162
+ &:where(:not([disabled])) {
163
+ &:where(:not(:active):hover) {
164
+ --_bg-color: var(--color-9);
165
+ --_border-color: var(--color-9);
166
+ }
167
+
168
+ &:where(:active) {
169
+ --_bg-color: var(--color-7);
170
+ --_border-color: var(--color-7);
171
+ }
172
+ }
173
+
174
+ &:where([disabled]) {
175
+ --_bg-color: color-mix(
176
+ in oklch,
177
+ var(--text-color-2) 8%,
178
+ var(--surface-default)
179
+ );
180
+ --_text-color: color-mix(
181
+ in oklch,
182
+ var(--text-color-2) 70%,
183
+ var(--surface-default)
184
+ );
185
+ }
186
+ }
187
+ &.filled {
188
+ --_bg-color: var(--color-8);
189
+ --_text-color: var(--color-1);
190
+
191
+ &:where(:not([disabled])) {
192
+ &:where(:not(:active):hover) {
193
+ --_bg-color: var(--color-10);
194
+ --_border-color: var(--color-10);
195
+ }
196
+
197
+ &:where(:active) {
198
+ --_bg-color: var(--color-9);
199
+ --_border-color: var(--color-9);
200
+ }
201
+ }
202
+
203
+ &:where([disabled]) {
204
+ --_bg-color: color-mix(
205
+ in oklch,
206
+ var(--text-color-2) 20%,
207
+ var(--surface-default)
208
+ );
209
+ --_text-color: color-mix(
210
+ in oklch,
211
+ var(--text-color-2) 70%,
212
+ var(--surface-default)
213
+ );
214
+ }
215
+ }
216
+ }
217
+
218
+ /* file input */
219
+ :where(input[type="file"]) {
220
+ align-self: flex-start;
221
+ border-radius: var(--radius-2);
222
+ border: var(--border-size-1) solid var(--surface-filled);
223
+ box-shadow: var(--inner-shadow-4);
224
+ color: var(--text-color-2-contrast);
225
+ cursor: initial;
226
+ max-inline-size: 100%;
227
+ padding: 0;
228
+ }
229
+
230
+ :where(input[type="file"])::-webkit-file-upload-button,
231
+ :where(input[type="file"])::file-selector-button {
232
+ cursor: pointer;
233
+ margin-inline-end: var(--size-relative-6);
234
+ }
235
+ }
236
+
237
+ @layer components.root {
238
+ :where(.icon-button) {
239
+ --_text-color: inherit;
240
+
241
+ align-items: center;
242
+ aspect-ratio: 1;
243
+ background-color: transparent;
244
+ border: 0;
245
+ border-radius: var(--radius-round);
246
+ display: inline-flex;
247
+ inline-size: var(--size-6);
248
+ justify-content: center;
249
+ padding: 0;
250
+ transform-style: preserve-3d;
251
+
252
+ &:where([disabled]) {
253
+ color: light-dark(rgb(0, 0, 0/0.3), rgb(255, 255, 255/0.26));
254
+ cursor: not-allowed;
255
+ opacity: 0.64;
256
+ }
257
+
258
+ svg {
259
+ max-inline-size: var(--size-5);
260
+ pointer-events: none;
261
+ }
262
+
263
+ /* Ripple effect, utils.css */
264
+ &::before {
265
+ --highlight-size: 130%;
266
+ }
267
+
268
+ /* Size */
269
+ &.small {
270
+ inline-size: var(--size-4);
271
+ svg {
272
+ max-inline-size: var(--size-4);
273
+ }
274
+ }
275
+ }
276
+ }
277
+
278
+ @layer components.root {
279
+ :where(nav.tabs) {
280
+ --_bg-color: transparent;
281
+
282
+ & > [role="tablist"] {
283
+ button {
284
+ outline-color: transparent;
285
+ outline-offset: -4px;
286
+
287
+ &[aria-selected="true"] {
288
+ &:focus-visible {
289
+ outline: 2px solid var(--text-color-1);
290
+ }
291
+ }
292
+ }
293
+ }
294
+
295
+ /* Underlined */
296
+ &.underlined {
297
+ /* Tab list */
298
+ & > [role="tablist"] {
299
+ border-bottom: 1px solid var(--border-color);
300
+
301
+ button {
302
+ --_ripple-color: light-dark(
303
+ color-mix(in oklch, var(--gray-2) 80%, var(--color-8)),
304
+ color-mix(in oklch, var(--gray-13) 80%, var(--color-8))
305
+ );
306
+
307
+ background: var(--_bg-color) var(--ripple, none);
308
+ font-weight: 500;
309
+ line-height: var(--font-lineheight-4);
310
+ padding: var(--size-2) var(--size-3);
311
+
312
+ &:focus-visible {
313
+ border-radius: 0;
314
+ }
315
+
316
+ &[aria-selected="true"] {
317
+ border-block-end: 2px solid var(--primary);
318
+ color: var(--primary);
319
+ }
320
+
321
+ @media (prefers-reduced-motion: no-preference) {
322
+ transition: background-color 0.2s var(--ease-out-3),
323
+ border-color 0.2s var(--ease-out-3), color 0.2s var(--ease-out-3),
324
+ outline-offset 0.05s var(--ease-1);
325
+
326
+ /*** Ripple effect */
327
+ background-position: center;
328
+ transition: background var(--button-ripple-duration);
329
+ &:where(:not(:active):hover) {
330
+ --ripple: radial-gradient(
331
+ circle,
332
+ transparent 1%,
333
+ var(--_ripple-color) 1%
334
+ )
335
+ center/15000%;
336
+ }
337
+
338
+ &:where(:hover:active) {
339
+ background-size: var(--button-ripple-size);
340
+ transition: background 0s;
341
+ }
342
+
343
+ &:hover {
344
+ background-color: light-dark(
345
+ oklch(from var(--primary) calc(l * 0.75) none h / 5%),
346
+ oklch(from var(--primary) calc(l * 1.25) none h / 5%)
347
+ );
348
+ }
349
+ }
350
+ }
351
+ }
352
+ }
353
+
354
+ /* Filled */
355
+ &.filled {
356
+ --_bg-color: var(--surface-default);
357
+ --_radius: var(--border-radius);
358
+ --_selected-bg: var(--surface-filled);
359
+
360
+ & > [role="tablist"] {
361
+ background-color: var(--_bg-color);
362
+ border: var(--border-width) solid var(--border-color);
363
+ border-radius: var(--_radius);
364
+ overflow: hidden;
365
+ padding: 0.792ex;
366
+ width: fit-content;
367
+
368
+ button {
369
+ background-color: var(--_bg-color);
370
+ border-radius: var(--_radius);
371
+ line-height: var(--font-lineheight-4);
372
+ padding-inline: var(--size-3);
373
+
374
+ &:hover {
375
+ background-color: oklch(from var(--_bg-color) calc(l * 1.25) c h);
376
+ }
377
+
378
+ &[aria-selected="true"] {
379
+ background-color: var(--_selected-bg);
380
+
381
+ &:hover {
382
+ background-color: oklch(
383
+ from var(--_selected-bg) calc(l * 1.25) c h
384
+ );
385
+ }
386
+ }
387
+
388
+ @media (prefers-reduced-motion: no-preference) {
389
+ transition: background-color 0.2s var(--ease-out-3),
390
+ border-color 0.2s var(--ease-out-3), color 0.2s var(--ease-out-3),
391
+ outline-offset 0.05s var(--ease-1);
392
+ }
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+
399
+ @layer components.root {
400
+ :where([role="group"].toggle-button-group) {
401
+ --_border-radius: var(--button-border-radius);
402
+ --_button-padding-inline: clamp(var(--size-2), 3cqi, var(--size-4));
403
+ --_max-width: auto;
404
+ --_icon-size: var(--size-4);
405
+
406
+ background-color: var(--surface-default);
407
+ border: 1px solid var(--border-color);
408
+ border-radius: var(--_border-radius);
409
+ display: flex;
410
+ grid-auto-columns: 1fr;
411
+ grid-auto-flow: column;
412
+ max-inline-size: var(--_max-width);
413
+ min-inline-size: max-content;
414
+ overflow: clip;
415
+
416
+ /* Size */
417
+ &.small {
418
+ button {
419
+ min-block-size: 2.1875rem; /* 35px */
420
+ }
421
+ }
422
+
423
+ &.x-small {
424
+ button {
425
+ min-block-size: var(--size-6); /* 30px */
426
+ }
427
+ }
428
+
429
+ &.fullwidth {
430
+ inline-size: 100%;
431
+ }
432
+
433
+ /* Button */
434
+ button {
435
+ --_bg-color: transparent;
436
+
437
+ align-items: center;
438
+ background: var(--_bg-color) var(--ripple, none);
439
+ border-radius: 0;
440
+ border-inline: 1px solid var(--border-color);
441
+ border-inline-start-width: 0;
442
+ color: var(--text-color-1);
443
+ display: inline-flex;
444
+ flex: auto;
445
+ gap: 1ex;
446
+ justify-content: center;
447
+ min-block-size: 2.5rem; /* 40px */
448
+ min-inline-size: 5ex;
449
+ outline-offset: calc(-1 * var(--size-2));
450
+ padding: 0 var(--_button-padding-inline);
451
+ position: relative;
452
+ user-select: none;
453
+
454
+ @media (prefers-reduced-motion: no-preference) {
455
+ transition: background-color 0.2s var(--ease-out-3),
456
+ box-shadow 0.2s var(--ease-out-3), border-color 0.2s var(--ease-out-3),
457
+ color 0.2s var(--ease-out-3), outline-offset 0.05s var(--ease-1);
458
+ }
459
+
460
+ /* Element states */
461
+ &:hover {
462
+ --_bg-color: light-dark(oklch(0% 0 0 / 0.04), oklch(100% 0 0 / 0.08));
463
+ }
464
+
465
+ &:focus-visible {
466
+ outline-offset: -6px;
467
+ }
468
+
469
+ /* Disabled */
470
+ &[disabled] {
471
+ border-color: color-mix(in oklch, var(--border-color) 50%, transparent);
472
+ cursor: not-allowed;
473
+ color: color-mix(in oklch, var(--text-color-1) 30%, transparent);
474
+ }
475
+
476
+ &[disabled] + &:not([disabled]):not(:last-of-type) {
477
+ border-inline-end-width: 1px;
478
+ }
479
+
480
+ /* Assign border radius for outline */
481
+ &:first-of-type {
482
+ border-bottom-left-radius: var(--_border-radius);
483
+ border-top-left-radius: var(--_border-radius);
484
+ }
485
+ &:last-of-type {
486
+ border-bottom-right-radius: var(--_border-radius);
487
+ border-top-right-radius: var(--_border-radius);
488
+ }
489
+
490
+ &:last-of-type {
491
+ border-inline-end-width: 0;
492
+ }
493
+
494
+ /* Ripple effect */
495
+ background-position: center;
496
+
497
+ &:where(:not([disabled])) {
498
+ &:where(:not(:active):hover) {
499
+ --ripple: radial-gradient(circle, transparent 1%, var(--_bg-color) 1%)
500
+ center/15000%;
501
+
502
+ transition: background var(--button-ripple-duration);
503
+ }
504
+
505
+ &:where(:hover:active) {
506
+ background-size: var(--button-ripple-size);
507
+ transition: background 0s;
508
+ }
509
+ }
510
+
511
+ /* Icons */
512
+ svg {
513
+ inline-size: var(--_icon-size);
514
+ inset-inline-start: calc(var(--_button-padding-inline));
515
+
516
+ & + svg {
517
+ max-block-size: var(--size-5);
518
+ max-inline-size: var(--size-7);
519
+ }
520
+ }
521
+
522
+ /* Selected */
523
+ &.selected {
524
+ --_bg-color: oklch(from var(--primary) l c h / 25%);
525
+
526
+ /* Checkmark */
527
+ svg:first-of-type {
528
+ margin-block-end: -3px;
529
+ }
530
+ }
531
+ }
532
+ }
533
+ }
534
+
535
+ @layer components.root {
536
+ :where(.avatar) {
537
+ --_bg-color: var(--color-8);
538
+ --_color: var(--text-color-1);
539
+ --_width: 40px;
540
+
541
+ align-items: center;
542
+ background-color: var(--_bg-color);
543
+ color: var(--_color);
544
+ aspect-ratio: 1;
545
+ border-radius: 100vmax;
546
+ display: inline-flex;
547
+ inline-size: var(--_width);
548
+ justify-content: center;
549
+ overflow: clip;
550
+ position: relative;
551
+ text-align: center;
552
+ text-decoration: none;
553
+
554
+ &:has(img) {
555
+ background-color: transparent;
556
+ }
557
+
558
+ svg {
559
+ max-inline-size: var(--size-5);
560
+ }
561
+
562
+ img {
563
+ block-size: 100%;
564
+ inline-size: 100%;
565
+ inset: 0;
566
+ object-fit: cover;
567
+ position: absolute;
568
+ }
569
+
570
+ &.squared {
571
+ border-radius: 0;
572
+ }
573
+
574
+ &.rounded {
575
+ border-radius: var(--border-size-3);
576
+ }
577
+ }
578
+
579
+ /*
580
+ TODO: implement reading-order if that becomes a thing.
581
+ https://developer.chrome.com/blog/reading-order/
582
+ */
583
+ :where(.avatar-group) {
584
+ --_margin: var(--size-1);
585
+
586
+ display: flex;
587
+ flex-direction: row-reverse;
588
+
589
+ &.gap-small {
590
+ --_margin: var(--size-2);
591
+ }
592
+
593
+ &.gap-x-small {
594
+ --_margin: var(--size-3);
595
+ }
596
+
597
+ .avatar {
598
+ margin-inline-end: calc(-1 * var(--_margin));
599
+ outline: 2px solid var(--surface-default);
600
+ }
601
+ }
602
+ }
603
+
604
+ @layer components.root {
605
+ :where(.badge) {
606
+ --_bg-color: var(--primary);
607
+ --_border-color: var(--primary);
608
+ --_color: var(--gray-1);
609
+ --_inset-offset: 16px;
610
+ --_inset: auto auto calc(100% - var(--_inset-offset))
611
+ calc(100% - var(--_inset-offset));
612
+ --_translate: 0;
613
+
614
+ display: inline-flex;
615
+ position: relative;
616
+
617
+ &::after {
618
+ background-color: var(--_bg-color);
619
+ border: 2px solid var(--_border-color);
620
+ border-radius: 100vmax;
621
+ color: var(--_color);
622
+ content: attr(aria-label);
623
+ font-size: 12px;
624
+ font-weight: 500;
625
+ block-size: var(--size-4);
626
+ line-height: normal;
627
+ min-inline-size: var(--size-4, 1.125rem);
628
+ padding-inline: var(--size-1);
629
+ inset: var(--_inset);
630
+ position: absolute;
631
+ text-align: center;
632
+ translate: var(--_translate);
633
+ transition: opacity 0.2s var(--ease-out-1);
634
+ inline-size: max-content;
635
+ }
636
+
637
+ /* Alignment */
638
+ &.start-start {
639
+ --_inset: auto calc(100% - var(--_inset-offset))
640
+ calc(100% - var(--_inset-offset)) auto;
641
+ }
642
+ &.start-end {
643
+ --_inset: auto auto calc(100% - var(--_inset-offset))
644
+ calc(100% - var(--_inset-offset));
645
+ }
646
+ &.end-start {
647
+ --_inset: calc(100% - var(--_inset-offset))
648
+ calc(100% - var(--_inset-offset)) auto auto;
649
+ }
650
+ &.end-end {
651
+ --_inset: calc(100% - var(--_inset-offset)) auto auto
652
+ calc(100% - var(--_inset-offset));
653
+ }
654
+
655
+ /* Dot */
656
+ &.dot {
657
+ --_inset: 0 -1px auto auto;
658
+ &::after {
659
+ content: "";
660
+ min-inline-size: var(--size-2);
661
+ block-size: var(--size-2);
662
+ inline-size: var(--size-2);
663
+ padding: 0;
664
+ }
665
+ }
666
+
667
+ /* Visibility */
668
+ &.invisible {
669
+ &::after {
670
+ opacity: 0;
671
+ pointer-events: none;
672
+ }
673
+ }
674
+
675
+ /* Colors */
676
+ &.error,
677
+ &.good,
678
+ &.ok,
679
+ &.warning {
680
+ --_bg-color: var(--color-8);
681
+ --_border-color: var(--color-8);
682
+ }
683
+ }
684
+
685
+ [dir="rtl"] {
686
+ :where(.badge) {
687
+ --_inset: auto calc(100% - 16px) calc(100% - 16px) auto;
688
+
689
+ /* Alignment */
690
+ &.start-start {
691
+ --_inset: auto auto calc(100% - 16px) calc(100% - 16px);
692
+ }
693
+ &.start-end {
694
+ --_inset: auto calc(100% - 16px) calc(100% - 16px) auto;
695
+ }
696
+ &.end-start {
697
+ --_inset: calc(100% - 16px) auto auto calc(100% - 16px);
698
+ }
699
+ &.end-end {
700
+ --_inset: calc(100% - 16px) calc(100% - 16px) auto auto;
701
+ }
702
+ }
703
+ }
704
+ }
705
+
706
+ @layer components.root {
707
+ :where(.card) {
708
+ --_bg-color: transparent;
709
+ --_border-color: transparent;
710
+ --_border-width: 0;
711
+ --_shadow: none;
712
+
713
+ background-color: var(--_bg-color);
714
+ border-color: var(--_border-color);
715
+ border-radius: var(--border-radius, 0.25rem);
716
+ border-style: solid;
717
+ border-width: var(--_border-width);
718
+ box-shadow: var(--_shadow);
719
+ display: flex;
720
+ flex-direction: column;
721
+ gap: var(--size-3);
722
+ overflow: hidden;
723
+ padding-inline: 0;
724
+
725
+ /* Variants */
726
+ &.text {
727
+ --_bg-color: transparent;
728
+ --_border-color: transparent;
729
+ --_border-width: 0;
730
+ --_shadow: none;
731
+ padding-inline: 0;
732
+ }
733
+
734
+ &.tonal {
735
+ --_bg-color: var(--surface-tonal);
736
+ --_border-width: 1px;
737
+ }
738
+
739
+ &.elevated {
740
+ --_bg-color: var(--surface-elevated);
741
+ --_border-color: transparent;
742
+ --_border-width: 0;
743
+ --_shadow: var(--shadow-3);
744
+
745
+ /* Adjust shadow in dark mode */
746
+ @container style(--color-scheme: dark) {
747
+ --_shadow: var(--shadow-4);
748
+ }
749
+ }
750
+
751
+ &.outlined {
752
+ --_bg-color: var(--surface-default);
753
+ --_border-color: var(--border-color);
754
+ --_border-width: 1px;
755
+ }
756
+
757
+ & > :where(hgroup, .content) {
758
+ padding-inline: var(--size-3);
759
+ }
760
+
761
+ & > hgroup {
762
+ padding-block: var(--size-3) 0;
763
+
764
+ /* Top paragraph */
765
+ & > p:first-of-type:first-child {
766
+ line-height: 1.3;
767
+ }
768
+
769
+ /* Bottom paragraph */
770
+ & > p:last-of-type:last-child:not(:first-child) {
771
+ font-size: var(--font-size-1, 1rem);
772
+ }
773
+ }
774
+
775
+ & > .content:where(:only-child, :first-child) {
776
+ padding-block: var(--size-3) var(--size-4);
777
+ }
778
+
779
+ & > .actions {
780
+ display: flex;
781
+ gap: var(--size-1);
782
+ margin-block: var(--size-2) 0;
783
+ padding-block-end: var(--size-1);
784
+ padding-inline: var(--size-1) var(--size-3);
785
+ }
786
+ }
787
+ }
788
+
789
+ @layer components.root {
790
+ :where(.chip) {
791
+ --_bg-color: var(--surface-tonal);
792
+ --_border-color: var(--border-color);
793
+ --_color: var(--text-color-1);
794
+
795
+ align-items: center;
796
+ background: var(--_bg-color) var(--ripple, none);
797
+ border: 1px solid var(--_border-color);
798
+ border-radius: var(--radius-2, 0.5rem);
799
+ color: var(--_color);
800
+ display: inline-flex;
801
+ font-size: var(--font-size-0, 0.75rem);
802
+ gap: var(--size-1);
803
+ block-size: var(--size-7, 2rem);
804
+ padding-inline: var(--size-2);
805
+ text-decoration: none;
806
+
807
+ /* Variants */
808
+ &.tonal {
809
+ --_bg-color: var(--surface-tonal);
810
+ --_color: var(--text-color-1);
811
+ }
812
+
813
+ &.outlined {
814
+ --_bg-color: var(--surface-default);
815
+ --_color: var(--text-color-1);
816
+ }
817
+
818
+ /* TODO: should this be out of the box? */
819
+ /* Colors */
820
+ /* &:hover {
821
+ --_bg-color: var(--color-11);
822
+ --_border-color: var(--color-11);
823
+ --_color: var(--text-color-1);
824
+ } */
825
+ /* &.red,
826
+ &.blue,
827
+ &.green,
828
+ &.orange,
829
+ &.primary {
830
+ --_bg-color: var(--color-5);
831
+ --_border-color: var(--color-7);
832
+ --_color: var(--text-color-1-contrast);
833
+
834
+ &:hover {
835
+ --_bg-color: var(--color-7);
836
+ --_border-color: var(--color-7);
837
+ --_color: var(--text-color-1-contrast);
838
+
839
+ &:active {
840
+ --_bg-color: var(--color-8);
841
+ --_border-color: var(--color-8);
842
+ }
843
+ }
844
+
845
+ &.outlined {
846
+ --_bg-color: var(--surface-tonal);
847
+ --_color: var(--text-color-1);
848
+ --_border-color: var(--color-9);
849
+
850
+ &:hover {
851
+ --_bg-color: var(--color-9);
852
+ --_border-color: var(--color-9);
853
+ --_color: var(--text-color-1);
854
+
855
+ &:active {
856
+ --_bg-color: var(--color-11);
857
+ --_border-color: var(--color-11);
858
+ }
859
+ }
860
+ }
861
+ } */
862
+
863
+ &:where(button, a):where(:not([disabled])) {
864
+ &:where(:not(:active)):hover {
865
+ --_bg-color: light-dark(
866
+ oklch(from var(--surface-tonal) calc(l * 0.98) c h),
867
+ oklch(from var(--surface-tonal) calc(l * 1.1) c h)
868
+ );
869
+ }
870
+ }
871
+
872
+ /* Icon */
873
+ &:has(svg:first-child) {
874
+ padding-inline: var(--size-1) var(--size-2);
875
+ }
876
+ &:has(svg:last-child) {
877
+ padding-inline: var(--size-2) var(--size-1);
878
+ }
879
+
880
+ &:has(svg) {
881
+ svg {
882
+ flex-shrink: 0;
883
+ inline-size: var(--size-3);
884
+ }
885
+ }
886
+
887
+ /* Sizes */
888
+ &.small {
889
+ block-size: var(--size-5);
890
+ }
891
+ &.multiline {
892
+ block-size: auto;
893
+ }
894
+
895
+ /* Ripple effect */
896
+ background-position: center;
897
+
898
+ &:where(:not([disabled])) {
899
+ &:where(:not(:active):hover) {
900
+ --ripple: radial-gradient(circle, transparent 1%, var(--_bg-color) 1%)
901
+ center/15000%;
902
+
903
+ transition: background var(--button-ripple-duration);
904
+ }
905
+
906
+ &:where(:hover:active) {
907
+ background-size: var(--button-ripple-size);
908
+ transition: background 0s;
909
+ }
910
+ }
911
+
912
+ /* Disabled */
913
+ &:where([disabled]) {
914
+ opacity: 0.64;
915
+ --_text-color: color-mix(
916
+ in oklch,
917
+ var(--text-color-2) 50%,
918
+ var(--surface-default)
919
+ );
920
+ cursor: not-allowed;
921
+ }
922
+ }
923
+ }
924
+
925
+ @layer components.root {
926
+ :where(.definition-list) {
927
+ --_border-style: solid;
928
+ --_border-width: 1px;
929
+
930
+ display: grid;
931
+ gap: var(--size-3);
932
+ padding: 0;
933
+
934
+ &.dotted {
935
+ --_border-style: dotted;
936
+ --_border-width: 2px;
937
+ }
938
+
939
+ li {
940
+ display: grid;
941
+ margin: 0;
942
+ padding: 0;
943
+
944
+ .term {
945
+ display: block;
946
+ font-weight: 700;
947
+ overflow: hidden;
948
+ position: relative;
949
+ }
950
+
951
+ hr {
952
+ display: none;
953
+ margin: 0;
954
+ }
955
+ }
956
+
957
+ @container (width > 45ch) {
958
+ gap: var(--size-1);
959
+
960
+ li {
961
+ align-items: baseline;
962
+ display: grid;
963
+ gap: var(--size-1);
964
+ grid-template-columns: 1fr auto;
965
+
966
+ &:has(hr) {
967
+ grid-template-columns: auto 1fr auto;
968
+ }
969
+
970
+ hr {
971
+ background-color: transparent;
972
+ border-block-end: var(--_border-width) var(--_border-style)
973
+ var(--border-color);
974
+ block-size: 2px;
975
+ display: block;
976
+ }
977
+
978
+ .term {
979
+ inline-size: max-content;
980
+
981
+ &::after {
982
+ display: inline-block;
983
+ }
984
+ }
985
+ .description {
986
+ color: var(--text-color-2);
987
+ text-align: end;
988
+ }
989
+ }
990
+ }
991
+ }
992
+ }
993
+
994
+ @layer components.root {
995
+ :where(hr) {
996
+ background-color: var(--border-color);
997
+ block-size: var(--border-size-1);
998
+ margin-block: var(--size-fluid-3);
999
+ }
1000
+ }
1001
+
1002
+ @layer components.root {
1003
+ :where(.link) {
1004
+ color: var(--primary);
1005
+ cursor: pointer;
1006
+ font-weight: 700;
1007
+ text-decoration: underline;
1008
+ text-decoration-color: var(--primary);
1009
+ text-underline-offset: 2px;
1010
+
1011
+ &[href] {
1012
+ &:hover,
1013
+ &:focus-visible {
1014
+ color: var(--primary-light);
1015
+ }
1016
+ }
1017
+
1018
+ @supports (-moz-appearance: none) {
1019
+ text-underline-offset: 2px;
1020
+ }
1021
+ }
1022
+ }
1023
+
1024
+ @layer components.root {
1025
+ :where(table) {
1026
+ border-collapse: collapse;
1027
+ display: block;
1028
+ margin: var(--size-3) 0;
1029
+ max-inline-size: 100%;
1030
+ position: relative;
1031
+
1032
+ /* Rows */
1033
+ tr {
1034
+ background-color: var(--surface-default);
1035
+ border-top: 1px solid var(--border-color);
1036
+
1037
+ &:hover {
1038
+ background-color: oklch(from var(--surface-filled) l c h / 75%);
1039
+ }
1040
+ }
1041
+
1042
+ /* Cells */
1043
+ th,
1044
+ td {
1045
+ border: 1px solid var(--border-color);
1046
+ padding: var(--size-1) var(--size-2);
1047
+ }
1048
+
1049
+ th {
1050
+ background-color: var(--surface-filled);
1051
+ color: var(--text-color-1);
1052
+ font-size: var(--font-size-sm, 0.75rem);
1053
+ font-weight: 600;
1054
+ text-align: start;
1055
+ }
1056
+
1057
+ td {
1058
+ font-size: var(--font-size-sm, 0.75rem);
1059
+ }
1060
+
1061
+ /* Caption */
1062
+ caption {
1063
+ caption-side: bottom;
1064
+ color: var(--text-color-2);
1065
+ font-size: var(--font-size-sm, 0.75rem);
1066
+ padding: var(--size-2) 0;
1067
+ text-align: start;
1068
+ }
1069
+
1070
+ /* Header */
1071
+ thead {
1072
+ position: sticky;
1073
+ top: 0;
1074
+ z-index: 1;
1075
+ }
1076
+
1077
+ /* Footer */
1078
+ tfoot {
1079
+ border-top: 2px solid var(--border-color);
1080
+
1081
+ tr {
1082
+ background-color: var(--surface-filled);
1083
+ }
1084
+
1085
+ td {
1086
+ color: var(--text-color-1);
1087
+ font-weight: 600;
1088
+ }
1089
+ }
1090
+
1091
+ /* Column group */
1092
+ colgroup col {
1093
+ border: none;
1094
+ }
1095
+
1096
+ @container (width < 60ch) {
1097
+ th,
1098
+ td {
1099
+ padding: var(--size-1) 0.875rem;
1100
+ }
1101
+ }
1102
+
1103
+ /* Dense */
1104
+ &.dense {
1105
+ th,
1106
+ td {
1107
+ padding: var(--size-1) var(--size-2);
1108
+ }
1109
+
1110
+ caption {
1111
+ padding: var(--size-1) 0;
1112
+ }
1113
+
1114
+ @container (width < 60ch) {
1115
+ th,
1116
+ td {
1117
+ padding: var(--size-1) var(--size-2);
1118
+ }
1119
+ }
1120
+ }
1121
+ }
1122
+ }
1123
+
1124
+ @layer components.root {
1125
+ :where(progress) {
1126
+ --_accent-color: var(--primary);
1127
+ --_bg-color: var(--surface-tonal);
1128
+
1129
+ appearance: none;
1130
+ background-color: var(--_bg-color);
1131
+ border-radius: var(--border-radius, 0.25rem);
1132
+ border: 0;
1133
+ display: inline-block;
1134
+ block-size: var(--size-1);
1135
+ overflow: hidden;
1136
+ position: relative;
1137
+ vertical-align: baseline;
1138
+ inline-size: 100%;
1139
+
1140
+ &::-webkit-progress-bar {
1141
+ border-radius: var(--border-radius, 0.25rem);
1142
+ background: none;
1143
+ }
1144
+
1145
+ &[value]::-webkit-progress-value {
1146
+ background-color: var(--_accent-color);
1147
+
1148
+ @media (prefers-reduced-motion: no-preference) {
1149
+ transition: inline-size 0.2s
1150
+ var(--ease-out-4, cubic-bezier(0, 0, 0.1, 1));
1151
+ }
1152
+ }
1153
+
1154
+ &::-moz-progress-bar {
1155
+ background-color: var(--_accent-color);
1156
+ }
1157
+ }
1158
+
1159
+ @media (prefers-reduced-motion: no-preference) {
1160
+ progress:indeterminate {
1161
+ background-color: var(--_bg-color);
1162
+
1163
+ &::after {
1164
+ animation: indeterminate 2s linear infinite;
1165
+ background-color: var(--_accent-color);
1166
+ content: "";
1167
+ inset: 0 auto 0 0;
1168
+ position: absolute;
1169
+ will-change: inset-inline-start, inset-inline-end;
1170
+ }
1171
+
1172
+ &[value]::-webkit-progress-value {
1173
+ background-color: transparent;
1174
+ }
1175
+
1176
+ &::-moz-progress-bar {
1177
+ background-color: transparent;
1178
+ }
1179
+ }
1180
+
1181
+ [dir="rtl"] {
1182
+ :where(progress):indeterminate {
1183
+ animation-direction: reverse;
1184
+
1185
+ &::after {
1186
+ animation-direction: reverse;
1187
+ }
1188
+ }
1189
+ }
1190
+ }
1191
+
1192
+ @keyframes indeterminate {
1193
+ 0% {
1194
+ left: -200%;
1195
+ right: 100%;
1196
+ }
1197
+ 60% {
1198
+ left: 107%;
1199
+ right: -8%;
1200
+ }
1201
+ 100% {
1202
+ left: 107%;
1203
+ right: -8%;
1204
+ }
1205
+ }
1206
+ }
1207
+
1208
+ @layer components.root {
1209
+ [aria-busy="true"]:not(
1210
+ input,
1211
+ select,
1212
+ textarea,
1213
+ html,
1214
+ progress,
1215
+ [aria-describedby]
1216
+ ) {
1217
+ position: relative;
1218
+
1219
+ &::before {
1220
+ animation: spin 0.7s linear infinite;
1221
+ border-color: transparent currentColor currentColor;
1222
+ border-radius: 50%;
1223
+ border-style: solid;
1224
+ border-width: 3px;
1225
+ content: "";
1226
+ display: inline-block;
1227
+ block-size: 1em;
1228
+ opacity: 0.5;
1229
+ vertical-align: -0.14em;
1230
+ inline-size: 1em;
1231
+ }
1232
+
1233
+ &:not(button.button):not(:empty) {
1234
+ &::before {
1235
+ margin-inline-end: 0.5em;
1236
+ }
1237
+ }
1238
+ }
1239
+
1240
+ @keyframes spin {
1241
+ to {
1242
+ transform: rotate(1turn);
1243
+ }
1244
+ }
1245
+ }
1246
+
1247
+ @layer components.root {
1248
+ label:where(.checkbox, .radio) {
1249
+ align-items: center;
1250
+ color: var(--text-color-1);
1251
+ cursor: pointer;
1252
+ display: inline-grid;
1253
+ gap: 0 var(--size-2);
1254
+ grid-auto-columns: auto;
1255
+ grid-auto-flow: column;
1256
+ inline-size: fit-content;
1257
+ line-height: 1.5;
1258
+ transform: translateZ(0);
1259
+ user-select: none;
1260
+
1261
+ /* Disabled */
1262
+ &:has([disabled]) {
1263
+ cursor: not-allowed;
1264
+ opacity: 0.64;
1265
+ user-select: none;
1266
+
1267
+ input {
1268
+ cursor: not-allowed;
1269
+ }
1270
+ }
1271
+
1272
+ /* Required dot */
1273
+ &:has([required]:not([type="checkbox"]:checked)) {
1274
+ .label:after {
1275
+ color: var(--red);
1276
+ content: "*";
1277
+ inset: 0 -0.25ex auto auto;
1278
+ position: absolute;
1279
+ }
1280
+ }
1281
+
1282
+ /* Label */
1283
+ .label {
1284
+ grid-column: 2;
1285
+ grid-row: 1;
1286
+ position: relative;
1287
+ padding-inline: 0 1ex;
1288
+ }
1289
+
1290
+ /* Supporting text */
1291
+ .supporting-text {
1292
+ color: var(--text-color-2);
1293
+ font-size: var(--font-size-xs);
1294
+ grid-column: 2;
1295
+ grid-row: 2;
1296
+ line-height: 1.5;
1297
+ z-index: 1;
1298
+ }
1299
+
1300
+ /* Stacked layout */
1301
+ &.stack {
1302
+ justify-items: center;
1303
+ grid-auto-columns: unset;
1304
+
1305
+ .label {
1306
+ grid-column: 1/-1;
1307
+ grid-row: 2;
1308
+ margin-block-start: var(--size-1);
1309
+ padding-inline: 1ex;
1310
+
1311
+ /* Required dot */
1312
+ &::after {
1313
+ inset: 0 -0.25ex auto auto;
1314
+ }
1315
+ }
1316
+
1317
+ .supporting-text {
1318
+ grid-column: 1/-1;
1319
+ grid-row: 3;
1320
+ }
1321
+ }
1322
+
1323
+ /* Input */
1324
+ input {
1325
+ aspect-ratio: 1;
1326
+ block-size: 1.125rem;
1327
+ cursor: pointer;
1328
+ inline-size: 1.125rem;
1329
+
1330
+ &::before {
1331
+ --highlight-size: 175%;
1332
+ }
1333
+ }
1334
+
1335
+ /* Sizes */
1336
+ &.small {
1337
+ input {
1338
+ block-size: var(--size-3);
1339
+ inline-size: var(--size-3);
1340
+ }
1341
+ }
1342
+
1343
+ &.large {
1344
+ input {
1345
+ block-size: var(--size-4);
1346
+ inline-size: var(--size-4);
1347
+ }
1348
+ }
1349
+
1350
+ /* Validation */
1351
+ &.error {
1352
+ input[type="checkbox"] {
1353
+ accent-color: var(--color-9);
1354
+
1355
+ & ~ :where(.label, .supporting-text) {
1356
+ color: var(--color-9);
1357
+ }
1358
+ }
1359
+ }
1360
+
1361
+ /* Touch devices */
1362
+ @media (pointer: coarse) {
1363
+ input {
1364
+ block-size: var(--size-4);
1365
+ inline-size: var(--size-4);
1366
+ }
1367
+ }
1368
+ }
1369
+ }
1370
+
1371
+ @layer components.root {
1372
+ :where(.switch) {
1373
+ --_accent-color: var(--primary);
1374
+ --_accent-contrast: var(--primary-contrast);
1375
+
1376
+ --_dot-bg-color: light-dark(var(--gray-11), var(--gray-14));
1377
+ --_dot-inset: var(--size-1) auto auto var(--size-1);
1378
+ --_dot-outline-size: 0;
1379
+ --_dot-size: var(--size-3);
1380
+
1381
+ --_track-bg-color: light-dark(var(--gray-3), var(--gray-8));
1382
+ --_track-height: var(--size-5);
1383
+ --_track-width: var(--size-8);
1384
+ --_transition-tf: var(--ease-4);
1385
+ --_transition-time: 0.2s;
1386
+
1387
+ align-items: center;
1388
+ color: var(--text-color-1);
1389
+ display: inline-grid;
1390
+ gap: 0 var(--size-2);
1391
+ grid-auto-columns: auto;
1392
+ grid-auto-flow: column;
1393
+ inline-size: fit-content;
1394
+
1395
+ input[type="checkbox"][role="switch"] {
1396
+ appearance: none;
1397
+ block-size: var(--_track-height);
1398
+ cursor: pointer;
1399
+ inline-size: var(--_track-width);
1400
+ margin: 0;
1401
+ position: relative;
1402
+
1403
+ /* Track */
1404
+ &::before {
1405
+ background-color: var(--_track-bg-color);
1406
+ block-size: var(--_track-height);
1407
+ border: 1px solid var(--_dot-bg-color);
1408
+ border-radius: 100vmax;
1409
+ content: "";
1410
+ inline-size: var(--_track-width);
1411
+ inset: 0;
1412
+ position: absolute;
1413
+ }
1414
+
1415
+ &:focus-visible {
1416
+ outline-offset: 2px;
1417
+ outline: 2px solid currentColor;
1418
+ }
1419
+
1420
+ /* Dot */
1421
+ &::after {
1422
+ background-color: var(--_dot-bg-color);
1423
+ block-size: var(--_dot-size);
1424
+ border-radius: 100vmax;
1425
+ content: "";
1426
+ inline-size: var(--_dot-size);
1427
+ inset: var(--_dot-inset);
1428
+ outline-offset: -1px;
1429
+ outline: var(--_dot-outline-size) solid var(--_dot-bg-color);
1430
+ position: absolute;
1431
+ }
1432
+
1433
+ /* Checked */
1434
+ &:checked {
1435
+ &::before {
1436
+ background-color: var(--_accent-color);
1437
+ border-color: var(--_accent-color);
1438
+ transition:
1439
+ background-color var(--_transition-time) var(--_transition-tf),
1440
+ border-color var(--_transition-time) var(--_transition-tf);
1441
+ }
1442
+
1443
+ /* Dot */
1444
+ &::after {
1445
+ --_dot-bg-color: var(--_accent-contrast);
1446
+ --_dot-outline-size: calc(var(--size-1) - 1px);
1447
+
1448
+ inset-inline-start: calc(
1449
+ var(--_track-width) - var(--_dot-size) - var(--size-1)
1450
+ );
1451
+ }
1452
+ }
1453
+
1454
+ /* Animation */
1455
+ @media (prefers-reduced-motion: no-preference) {
1456
+ /* Track */
1457
+ &::before {
1458
+ transition:
1459
+ background-color var(--_transition-time) var(--_transition-tf),
1460
+ border-color var(--_transition-time) var(--_transition-tf);
1461
+ }
1462
+
1463
+ /* Dot */
1464
+ &::after {
1465
+ transition: all var(--_transition-time) var(--_transition-tf);
1466
+ }
1467
+
1468
+ &:active:after {
1469
+ --_dot-outline-size: calc(var(--size-1) + 1px);
1470
+ }
1471
+
1472
+ &:checked {
1473
+ &:active:after {
1474
+ --_dot-outline-size: calc(var(--size-1) + 1px);
1475
+ }
1476
+ }
1477
+ }
1478
+ }
1479
+
1480
+ /* Icons */
1481
+ &:has(.icon-checked, .icon-unchecked) {
1482
+ [role="switch"] {
1483
+ grid-column: 1 / -1;
1484
+ grid-row: 1;
1485
+ }
1486
+
1487
+ &:has([role="switch"]:checked) {
1488
+ .icon-unchecked {
1489
+ display: none;
1490
+ }
1491
+ .icon-checked {
1492
+ display: block;
1493
+ }
1494
+ }
1495
+
1496
+ .icon-checked {
1497
+ display: none;
1498
+ }
1499
+
1500
+ svg {
1501
+ grid-column: 1;
1502
+ grid-row: 1;
1503
+ inline-size: var(--_dot-size);
1504
+ margin-inline-start: calc(
1505
+ var(--_track-width) - var(--_dot-size) - var(--size-1)
1506
+ );
1507
+ pointer-events: none;
1508
+ z-index: 1;
1509
+
1510
+ &.icon-checked {
1511
+ margin-inline-start: var(--size-1);
1512
+ }
1513
+ }
1514
+ }
1515
+
1516
+ /* Required dot */
1517
+ &:has([required]:not(:checked)) {
1518
+ .label:after {
1519
+ color: var(--red);
1520
+ content: "*";
1521
+ inset: 0 -0.25ex auto auto;
1522
+ position: absolute;
1523
+ }
1524
+ }
1525
+
1526
+ /* Disabled */
1527
+ &:has([disabled]) {
1528
+ cursor: not-allowed;
1529
+ opacity: 0.64;
1530
+ user-select: none;
1531
+
1532
+ input {
1533
+ cursor: not-allowed;
1534
+ }
1535
+ }
1536
+
1537
+ /* Label */
1538
+ .label {
1539
+ grid-column: 2;
1540
+ grid-row: 1;
1541
+ min-width: 0;
1542
+ padding-inline: 0 1ex;
1543
+ position: relative;
1544
+ user-select: none;
1545
+ }
1546
+
1547
+ /* Supporting text */
1548
+ .supporting-text {
1549
+ color: var(--text-color-2);
1550
+ font-size: var(--font-size-xs);
1551
+ grid-column: 2;
1552
+ grid-row: 2;
1553
+ line-height: 1.5;
1554
+ z-index: 1;
1555
+ }
1556
+
1557
+ /* Size */
1558
+ &.small {
1559
+ --_dot-size: 0.75rem;
1560
+ --_track-height: var(--size-4);
1561
+ --_track-width: 2.5rem;
1562
+ }
1563
+
1564
+ /* Stacked layout */
1565
+ &.stack {
1566
+ justify-items: center;
1567
+ grid-auto-columns: unset;
1568
+
1569
+ .label {
1570
+ grid-column: 1/-1;
1571
+ grid-row: 2;
1572
+ margin-block-start: var(--size-1);
1573
+ padding-inline: 1ex;
1574
+ }
1575
+
1576
+ .supporting-text {
1577
+ grid-column: 1/-1;
1578
+ grid-row: 3;
1579
+ }
1580
+ }
1581
+
1582
+ /* Validation */
1583
+ &.error {
1584
+ input {
1585
+ outline: 2px solid var(--color-9);
1586
+ border-radius: var(--radius-round);
1587
+ }
1588
+
1589
+ .label,
1590
+ .supporting-text {
1591
+ color: var(--color-9);
1592
+ }
1593
+ }
1594
+ }
1595
+ }
1596
+
1597
+ @layer components.root {
1598
+ :where(.range > input[type="range"]) {
1599
+ --thumb-bg: var(--primary);
1600
+ --thumb-highlight-color: oklch(from var(--primary) 70% 100% h / 20%);
1601
+ --thumb-highlight-size: 0px;
1602
+ --thumb-offset: -1ex;
1603
+ --thumb-size: 3ex;
1604
+ --track-color: var(--field-border-color);
1605
+ --track-fill: 0%;
1606
+ --track-height: 1ex;
1607
+
1608
+ appearance: none;
1609
+ background: transparent;
1610
+ display: block;
1611
+ inline-size: 100%;
1612
+ margin: 1ex 0 3ex;
1613
+ outline-offset: 1ex;
1614
+
1615
+ @media (hover: none) {
1616
+ --thumb-offset: -14px;
1617
+ --thumb-size: 30px;
1618
+ }
1619
+
1620
+ /* Track */
1621
+ &::-webkit-slider-runnable-track {
1622
+ appearance: none;
1623
+ background: linear-gradient(
1624
+ to right,
1625
+ transparent var(--track-fill),
1626
+ var(--track-color) 0%
1627
+ ),
1628
+ var(--primary);
1629
+ block-size: var(--track-height);
1630
+ border-radius: 5ex;
1631
+ box-shadow: var(--inner-shadow-1);
1632
+ }
1633
+
1634
+ &::-moz-range-track {
1635
+ appearance: none;
1636
+ background: linear-gradient(
1637
+ to right,
1638
+ transparent var(--track-fill),
1639
+ var(--track-color) 0%
1640
+ ),
1641
+ var(--primary);
1642
+ block-size: var(--track-height);
1643
+ border-radius: 5ex;
1644
+ box-shadow: var(--inner-shadow-2);
1645
+ }
1646
+
1647
+ /* Ring */
1648
+ &::-webkit-slider-thumb {
1649
+ appearance: none;
1650
+ background: var(--thumb-bg);
1651
+ block-size: var(--thumb-size);
1652
+ border-radius: 50%;
1653
+ border: 3px solid var(--surface-default);
1654
+ box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
1655
+ cursor: ew-resize;
1656
+ inline-size: var(--thumb-size);
1657
+ margin-block-start: var(--thumb-offset);
1658
+
1659
+ @media (prefers-reduced-motion: no-preference) {
1660
+ transition: box-shadow 0.1s ease;
1661
+ }
1662
+
1663
+ .fieldset-item:focus-within & {
1664
+ border-color: var(--gray-14);
1665
+ }
1666
+ }
1667
+
1668
+ &::-moz-range-thumb {
1669
+ appearance: none;
1670
+ background: var(--thumb-bg);
1671
+ block-size: var(--thumb-size);
1672
+ border-radius: 50%;
1673
+ border: 3px solid var(--primary);
1674
+ box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
1675
+ cursor: ew-resize;
1676
+ inline-size: var(--thumb-size);
1677
+ margin-block-start: var(--thumb-offset);
1678
+
1679
+ @media (prefers-reduced-motion: no-preference) {
1680
+ transition: box-shadow 0.1s ease;
1681
+ }
1682
+
1683
+ .fieldset-item:focus-within & {
1684
+ border-color: var(--gray-14);
1685
+ }
1686
+ }
1687
+
1688
+ /* Element state */
1689
+ &:not([disabled]) {
1690
+ &:hover {
1691
+ --thumb-highlight-size: var(--size-1);
1692
+ }
1693
+
1694
+ &:active {
1695
+ --thumb-highlight-size: var(--size-2);
1696
+ --track-color: light-dark(
1697
+ oklch(from var(--field-border-color) calc(l * 0.9) c h),
1698
+ oklch(from var(--field-border-color) calc(l * 1.1) c h)
1699
+ );
1700
+ }
1701
+ }
1702
+
1703
+ &[disabled] {
1704
+ --thumb-bg: oklch(from var(--text-color-1) l c h / 50%);
1705
+ --track-color: var(--field-border-color);
1706
+
1707
+ cursor: not-allowed;
1708
+
1709
+ &::-webkit-slider-thumb {
1710
+ cursor: not-allowed;
1711
+ }
1712
+ &::-moz-range-thumb {
1713
+ cursor: not-allowed;
1714
+ }
1715
+ }
1716
+ }
1717
+ }
1718
+
1719
+ @layer components.root {
1720
+ /* Base typography */
1721
+ :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
1722
+ color: var(--text-color-1);
1723
+ font-weight: 700;
1724
+ text-wrap: pretty;
1725
+ }
1726
+
1727
+ :where(h1, .h1) {
1728
+ font-size: var(--font-size-h1, var(--font-size-7));
1729
+ letter-spacing: -0.02em;
1730
+ line-height: 1.15;
1731
+ }
1732
+
1733
+ :where(h2, .h2) {
1734
+ font-size: var(--font-size-h2, var(--font-size-5, 2rem));
1735
+ letter-spacing: -0.02em;
1736
+ line-height: 1.2;
1737
+ }
1738
+
1739
+ :where(h3, .h3) {
1740
+ font-size: var(--font-size-h3, var(--font-size-4, 1.5rem));
1741
+ letter-spacing: -0.01em;
1742
+ line-height: 1.167;
1743
+ }
1744
+
1745
+ :where(h4, .h4) {
1746
+ font-size: var(--font-size-h4, var(--font-size-3, 1.25rem));
1747
+ letter-spacing: -0.01em;
1748
+ line-height: 1.235;
1749
+ }
1750
+
1751
+ :where(h5, .h5) {
1752
+ font-size: var(--font-size-h5, var(--font-size-2, 1.1rem));
1753
+ line-height: 1.334;
1754
+ }
1755
+
1756
+ :where(h6, .h6) {
1757
+ font-size: var(--font-size-h6, var(--font-size-1, 1rem));
1758
+ line-height: 1;
1759
+ }
1760
+
1761
+ :where(hgroup) {
1762
+ & > :where(p, .p) {
1763
+ margin: 0;
1764
+ }
1765
+
1766
+ & > :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
1767
+ margin-block-end: 0.4em;
1768
+ }
1769
+
1770
+ /* The second p element */
1771
+ & > :where(p, .p):last-of-type:last-child:not(:first-child) {
1772
+ color: oklch(from currentColor l c h / 75%);
1773
+ font-size: var(--font-size-lg);
1774
+ line-height: 1.6;
1775
+ }
1776
+ }
1777
+
1778
+ /** Overline */
1779
+ :where(.overline, hgroup > :where(p, .p):first-of-type:first-child) {
1780
+ color: light-dark(
1781
+ oklch(from var(--text-color-2) calc(l * 1.25) c h),
1782
+ oklch(from var(--text-color-2) calc(l * 0.75) c h)
1783
+ );
1784
+ font-size: var(--font-size-xs);
1785
+ font-weight: 500;
1786
+ letter-spacing: 0.06em;
1787
+ line-height: 2.5;
1788
+ text-transform: uppercase;
1789
+ }
1790
+
1791
+ :where(p, .p) {
1792
+ text-wrap: pretty;
1793
+
1794
+ &.small {
1795
+ font-size: var(--font-size-md);
1796
+ }
1797
+ &.large {
1798
+ font-size: var(--font-size-lg);
1799
+ }
1800
+ }
1801
+
1802
+ /* Inline text elements */
1803
+ :where(ins, u, abbr, dfn) {
1804
+ text-decoration: underline;
1805
+ text-underline-offset: 1px;
1806
+
1807
+ @supports (-moz-appearance: none) {
1808
+ text-underline-offset: 2px;
1809
+ }
1810
+ }
1811
+
1812
+ :where(abbr, dfn) {
1813
+ font-style: normal;
1814
+ text-decoration: var(--color-9) underline dotted;
1815
+
1816
+ &[title] {
1817
+ cursor: help;
1818
+ text-underline-offset: 1px;
1819
+ }
1820
+
1821
+ @supports (-moz-appearance: none) {
1822
+ text-underline-offset: 2px;
1823
+ }
1824
+ }
1825
+
1826
+ :where(sup) {
1827
+ font-size: 0.5em;
1828
+ }
1829
+
1830
+ :where(del, ins) {
1831
+ color: var(--color-9);
1832
+ }
1833
+
1834
+ :where(small) {
1835
+ font-size: max(0.5em, var(--font-size-0, 0.75rem));
1836
+ max-inline-size: var(--size-content-1);
1837
+ }
1838
+
1839
+ :where(cite) {
1840
+ font-style: italic;
1841
+ }
1842
+
1843
+ /* Blockquote */
1844
+ :where(blockquote) {
1845
+ border-inline-start-width: var(--border-size-3);
1846
+ display: grid;
1847
+ gap: var(--size-3);
1848
+ padding-block: var(--size-3);
1849
+ padding-inline: var(--size-4);
1850
+
1851
+ :first-child {
1852
+ margin-block-start: 0;
1853
+ }
1854
+
1855
+ :last-child {
1856
+ margin-block-end: 0;
1857
+ }
1858
+
1859
+ footer {
1860
+ color: var(--text-color-2);
1861
+ }
1862
+ }
1863
+
1864
+ /* Code */
1865
+ :where(pre) {
1866
+ border-radius: 0.375rem;
1867
+ direction: ltr;
1868
+ font-size: 0.875rem;
1869
+ line-height: 1.7142857;
1870
+ margin-block: 1.7142857em;
1871
+ max-inline-size: max-content;
1872
+ min-inline-size: 0;
1873
+ padding-block: 0.8571429em;
1874
+ padding-inline: 1.1428571em;
1875
+ white-space: pre;
1876
+ writing-mode: lr;
1877
+ }
1878
+
1879
+ :where(code, kbd, samp, pre) {
1880
+ font-family: var(--font-mono);
1881
+ }
1882
+
1883
+ :where(code) {
1884
+ background-color: oklch(00 0 0 /18%);
1885
+ border-radius: var(--border-size-3);
1886
+ font-size: 0.9em;
1887
+ padding: 0.2ex 0.5ex;
1888
+ }
1889
+
1890
+ :where(kbd, var) {
1891
+ background-color: var(--text-color-2);
1892
+ border-color: var(--text-color-2);
1893
+ border-radius: var(--border-radius, var(--radius-2));
1894
+ border-width: var(--border-size-1);
1895
+ color: var(--text-color-2-contrast);
1896
+ padding: calc(var(--size-1) / 2) var(--size-1);
1897
+ }
1898
+
1899
+ :where(:not(pre) code, kbd) {
1900
+ word-break: break-word;
1901
+ }
1902
+
1903
+ :where(:not(pre) code) {
1904
+ border-radius: var(--border-radius, var(--radius-2));
1905
+ padding: var(--size-1) var(--size-2);
1906
+ writing-mode: lr;
1907
+ }
1908
+
1909
+ :where(mark) {
1910
+ border-radius: var(--border-radius, 0);
1911
+ box-decoration-break: clone;
1912
+ padding: calc(var(--size-1) / 2) var(--size-1);
1913
+ vertical-align: baseline;
1914
+ }
1915
+
1916
+ /* Misc */
1917
+ :where(dt) {
1918
+ font-weight: 700;
1919
+ }
1920
+
1921
+ :where(figure) {
1922
+ & > :where(figcaption) {
1923
+ font-size: var(--font-size-1, 1rem);
1924
+ text-wrap: balance;
1925
+ }
1926
+ }
1927
+ }
1928
+
1929
+ /*** Extended components (has dependencies) */
1930
+
1931
+ @layer components.extended {
1932
+ :where([role="group"].button-group) {
1933
+ --_border-radius: var(--button-border-radius);
1934
+
1935
+ border-radius: var(--_border-radius);
1936
+ display: inline-flex;
1937
+ min-width: max-content;
1938
+
1939
+ button {
1940
+ border-radius: 0;
1941
+
1942
+ svg {
1943
+ max-inline-size: 0.7lh;
1944
+ }
1945
+
1946
+ &:focus-visible {
1947
+ outline-offset: -4px;
1948
+ }
1949
+
1950
+ & + & {
1951
+ border-inline-width: 1px;
1952
+ margin-inline-start: -1px;
1953
+ }
1954
+
1955
+ &:first-of-type {
1956
+ border-bottom-left-radius: var(--_border-radius);
1957
+ border-top-left-radius: var(--_border-radius);
1958
+ }
1959
+ &:last-of-type {
1960
+ border-bottom-right-radius: var(--_border-radius);
1961
+ border-top-right-radius: var(--_border-radius);
1962
+ }
1963
+
1964
+ /* Variants */
1965
+ &:where(.tonal, .filled) {
1966
+ & + button {
1967
+ border-inline-start-color: var(--color-7);
1968
+ }
1969
+
1970
+ & + &[disabled] {
1971
+ border-inline-start-color: color-mix(
1972
+ in oklch,
1973
+ var(--border-color) 90%,
1974
+ white
1975
+ );
1976
+ }
1977
+ }
1978
+ }
1979
+ }
1980
+ }
1981
+
1982
+ @layer components.extended {
1983
+ :where(details) {
1984
+ --_accordion-transition-time: 0.2s;
1985
+ --_bg-color: transparent;
1986
+ --_margin-inline: var(--size-1);
1987
+ --_shadow: none;
1988
+
1989
+ background-color: var(--_bg-color);
1990
+ box-shadow: var(--_shadow);
1991
+ border-radius: var(--border-radius, 4px);
1992
+ display: block;
1993
+ margin-inline: var(--_margin-inline);
1994
+ transition: all var(--_accordion-transition-time) ease-out;
1995
+
1996
+ /* Accordion animation */
1997
+ /* https://nerdy.dev/open-and-close-transitions-for-the-details-element */
1998
+ @media (prefers-reduced-motion: no-preference) {
1999
+ interpolate-size: allow-keywords;
2000
+ }
2001
+
2002
+ &::details-content {
2003
+ block-size: 0;
2004
+ opacity: 0;
2005
+ overflow-y: clip;
2006
+ transition:
2007
+ content-visibility var(--_accordion-transition-time) allow-discrete,
2008
+ opacity var(--_accordion-transition-time),
2009
+ block-size var(--_accordion-transition-time);
2010
+ }
2011
+
2012
+ &[open]::details-content {
2013
+ block-size: auto;
2014
+ opacity: 1;
2015
+ }
2016
+ /***/
2017
+
2018
+ & > summary {
2019
+ background-color: inherit;
2020
+ cursor: pointer;
2021
+ font-weight: 700;
2022
+ padding-block: var(--size-3);
2023
+ user-select: none;
2024
+ }
2025
+
2026
+ /* Custom arrow */
2027
+ /* summary {
2028
+ align-items: center;
2029
+ background-color: inherit;
2030
+ cursor: pointer;
2031
+ display: flex;
2032
+ justify-content: space-between;
2033
+ list-style: none;
2034
+ padding-block: var(--size-3);
2035
+ user-select: none;
2036
+
2037
+ &::marker,
2038
+ &::-webkit-details-marker {
2039
+ display: none;
2040
+ }
2041
+
2042
+ svg {
2043
+ transition: rotate 0.2s ease-out;
2044
+ }
2045
+ }
2046
+
2047
+ &[open] > summary svg {
2048
+ rotate: 180deg;
2049
+ } */
2050
+
2051
+ & > .content {
2052
+ margin-block-start: 0;
2053
+ padding-block: var(--size-2) var(--size-3);
2054
+ }
2055
+
2056
+ & > .actions {
2057
+ display: flex;
2058
+ gap: var(--size-1);
2059
+ justify-content: end;
2060
+ margin-block-start: var(--size-3);
2061
+ padding-block-end: var(--size-1);
2062
+ padding-inline: var(--size-3) var(--size-1);
2063
+ }
2064
+
2065
+ /* Variants */
2066
+ &.card,
2067
+ &.text {
2068
+ --_bg-color: transparent;
2069
+ --_margin-inline: var(--size-1);
2070
+ }
2071
+
2072
+ &.elevated {
2073
+ --_bg-color: var(--surface-elevated);
2074
+ --_margin-inline: 0;
2075
+ --_shadow: var(--shadow-2);
2076
+ }
2077
+
2078
+ &.outlined {
2079
+ --_bg-color: var(--surface-default);
2080
+ --_margin-inline: 0;
2081
+ border: 1px solid var(--border-color);
2082
+ }
2083
+
2084
+ &.tonal {
2085
+ --_bg-color: var(--surface-tonal);
2086
+ --_margin-inline: 0;
2087
+ }
2088
+
2089
+ &:where(.elevated, .outlined, .tonal) > * {
2090
+ padding-inline: var(--size-3);
2091
+ }
2092
+ }
2093
+
2094
+ /* Accordion group */
2095
+ :where(.card:has(details)) {
2096
+ --_gutter-color: var(--border-color);
2097
+
2098
+ display: block;
2099
+
2100
+ & > .content {
2101
+ margin-block: 0;
2102
+ padding: 0;
2103
+ }
2104
+
2105
+ &.card,
2106
+ &.text {
2107
+ &:not(.tonal, .outlined, .elevated) {
2108
+ summary {
2109
+ padding-inline: 0;
2110
+ }
2111
+ }
2112
+ }
2113
+
2114
+ & > details {
2115
+ --_margin-inline: 0;
2116
+
2117
+ border: 0;
2118
+ box-shadow: none;
2119
+
2120
+ & > * {
2121
+ padding-inline: var(--size-3);
2122
+ }
2123
+
2124
+ /* Border between accordion items */
2125
+ & + & {
2126
+ summary {
2127
+ border-radius: 0;
2128
+ border-block-start: 1px solid var(--_gutter-color);
2129
+ }
2130
+ }
2131
+
2132
+ /* First item */
2133
+ &:first-of-type {
2134
+ border-start-start-radius: var(--border-radius, 0.25rem);
2135
+ border-start-end-radius: var(--border-radius, 0.25rem);
2136
+ summary {
2137
+ border-start-start-radius: var(--border-radius, 0.25rem);
2138
+ border-start-end-radius: var(--border-radius, 0.25rem);
2139
+ }
2140
+ }
2141
+
2142
+ /* Last item */
2143
+ &:last-of-type {
2144
+ border-end-start-radius: var(--border-radius, 0.25rem);
2145
+ border-end-end-radius: var(--border-radius, 0.25rem);
2146
+ summary {
2147
+ border-end-start-radius: var(--border-radius, 0.25rem);
2148
+ border-end-end-radius: var(--border-radius, 0.25rem);
2149
+ }
2150
+ }
2151
+ }
2152
+ }
2153
+ }
2154
+
2155
+ @layer components.extended {
2156
+ /*
2157
+ Lists meant to be used stand-alone or as part of Select elements
2158
+
2159
+ Intended use-case:
2160
+ - ul.list > li
2161
+ - .select > .list > option
2162
+ */
2163
+ :where(.list) {
2164
+ --_bg-color: light-dark(var(--gray-1), var(--gray-15));
2165
+ --_bg-color-hover: light-dark(var(--gray-2), var(--gray-14));
2166
+
2167
+ background-color: var(--_bg-color);
2168
+ list-style: none;
2169
+ padding: var(--size-2) 0;
2170
+
2171
+ @media (pointer: coarse) {
2172
+ &,
2173
+ * {
2174
+ user-select: none;
2175
+ }
2176
+ }
2177
+
2178
+ /* Borders on all list items */
2179
+ &.bordered {
2180
+ :where(li + li, option + option) {
2181
+ margin-block-start: var(--size-3);
2182
+ &::before {
2183
+ block-size: 1px;
2184
+ border-block-start: 1px solid var(--border-color);
2185
+ content: "";
2186
+ display: block;
2187
+ inline-size: 100%;
2188
+ inset: calc(-1 * var(--size-2)) 0 auto 0;
2189
+ position: absolute;
2190
+ visibility: visible; /* override select > option:before style */
2191
+ }
2192
+ }
2193
+ }
2194
+
2195
+ /* Dense - less gaps and spacing */
2196
+ &.dense {
2197
+ :where(li, option) {
2198
+ gap: var(--size-2);
2199
+ min-block-size: var(--size-7);
2200
+ padding: var(--size-1) var(--size-2);
2201
+
2202
+ &.border-top {
2203
+ margin-block-start: var(--size-2);
2204
+ &::before {
2205
+ inset: calc(-1 * var(--size-1)) 0 auto 0;
2206
+ }
2207
+ }
2208
+
2209
+ /* Clickable list item */
2210
+ &:has(> a, > button, > label) {
2211
+ min-block-size: auto;
2212
+ padding: 0;
2213
+ }
2214
+
2215
+ & > :where(a, button, label) {
2216
+ gap: var(--size-2);
2217
+ min-block-size: var(--size-7);
2218
+ padding: var(--size-1) var(--size-2);
2219
+ }
2220
+
2221
+ /* Checkbox / Radio */
2222
+ & > label {
2223
+ .end {
2224
+ padding-inline-end: 0.125rem;
2225
+ }
2226
+ }
2227
+
2228
+ /* Leading and trailing content */
2229
+ .start,
2230
+ .end {
2231
+ .avatar {
2232
+ max-inline-size: var(--size-6);
2233
+ }
2234
+
2235
+ .icon-button,
2236
+ svg {
2237
+ max-inline-size: var(--size-4);
2238
+ }
2239
+
2240
+ .checkbox,
2241
+ .radio {
2242
+ max-inline-size: var(--size-3);
2243
+ }
2244
+ }
2245
+ }
2246
+ }
2247
+
2248
+ /* Gutterless */
2249
+ &.gutterless {
2250
+ :where(li, option) {
2251
+ padding-inline: 0;
2252
+
2253
+ & > :where(a, button, label) {
2254
+ padding-inline: 0;
2255
+ }
2256
+ }
2257
+ }
2258
+
2259
+ /* List item */
2260
+ :where(li, option, [role="group"] > label) {
2261
+ align-items: center;
2262
+ background: var(--_bg-color) var(--ripple, none);
2263
+ display: flex;
2264
+ font-size: var(--font-size-sm);
2265
+ gap: var(--size-3);
2266
+ isolation: isolate;
2267
+ min-block-size: 40px;
2268
+ padding: var(--size-2) var(--size-3);
2269
+ position: relative;
2270
+
2271
+ &::before {
2272
+ display: none; /* removing checkmark from option */
2273
+ }
2274
+
2275
+ * {
2276
+ font-size: inherit;
2277
+ }
2278
+
2279
+ /* Clickable list item */
2280
+ &:has(> a, > button, > label) {
2281
+ background: transparent;
2282
+ display: block;
2283
+ min-block-size: auto;
2284
+ padding: 0;
2285
+ }
2286
+
2287
+ /* Select option */
2288
+ &:where(option) {
2289
+ align-items: center;
2290
+ background-color: var(--_bg-color);
2291
+ color: inherit;
2292
+ cursor: pointer;
2293
+ display: flex;
2294
+ gap: var(--size-3);
2295
+ inline-size: 100%;
2296
+ margin: 0;
2297
+ min-block-size: 40px;
2298
+ padding: var(--size-2) var(--size-3);
2299
+ text-align: start;
2300
+ text-decoration: none;
2301
+ z-index: 0;
2302
+
2303
+ &:hover {
2304
+ background-color: var(--_bg-color-hover);
2305
+ }
2306
+
2307
+ &:checked {
2308
+ background-color: oklch(from var(--primary) l c h / 30%);
2309
+ }
2310
+ }
2311
+
2312
+ & > a,
2313
+ & > button,
2314
+ & > label {
2315
+ align-items: center;
2316
+ background: var(--_bg-color) var(--ripple, none);
2317
+ color: inherit;
2318
+ cursor: pointer;
2319
+ display: flex;
2320
+ gap: var(--size-3);
2321
+ inline-size: 100%;
2322
+ margin: 0;
2323
+ min-block-size: 40px;
2324
+ outline-offset: -3px;
2325
+ padding: var(--size-2) var(--size-3);
2326
+ text-align: start;
2327
+ text-decoration: none;
2328
+ z-index: 0;
2329
+
2330
+ /*** Ripple effect */
2331
+ background-position: center;
2332
+ transition: background var(--button-ripple-duration);
2333
+ &:where(:not(:active):hover) {
2334
+ --ripple: radial-gradient(circle, transparent 1%, var(--_bg-color) 1%)
2335
+ center/15000%;
2336
+ }
2337
+
2338
+ &:where(:hover:active) {
2339
+ background-size: var(--button-ripple-size);
2340
+ transition: background 0s;
2341
+ }
2342
+
2343
+ &:hover {
2344
+ background-color: var(--_bg-color-hover);
2345
+ }
2346
+
2347
+ /*** Remove ripple effect when trailing button is clicked */
2348
+ &:has(.end:hover) {
2349
+ &:where(:not(:active):hover) {
2350
+ --ripple: none;
2351
+ }
2352
+ }
2353
+ }
2354
+
2355
+ /* Checkbox / Radio / Switch */
2356
+ & > label {
2357
+ .end {
2358
+ padding-inline-end: var(--size-1);
2359
+ }
2360
+
2361
+ &:where(.checkbox, .radio) {
2362
+ inline-size: 100%;
2363
+ }
2364
+
2365
+ &.switch {
2366
+ --_dot-size: 0.75rem;
2367
+ --_track-height: var(--size-4);
2368
+ --_track-width: 2.5rem;
2369
+ }
2370
+ }
2371
+
2372
+ /* Video */
2373
+ &:has(video) {
2374
+ padding: 0.75rem var(--size-3) 0.75rem 0;
2375
+ }
2376
+
2377
+ /* Border between list items */
2378
+ &.border-top {
2379
+ margin-block-start: var(--size-3);
2380
+ &::before {
2381
+ block-size: 1px;
2382
+ border-block-start: 1px solid var(--border-color);
2383
+ content: "";
2384
+ display: block;
2385
+ inline-size: 100%;
2386
+ inset: calc(-1 * var(--size-2)) 0 auto 0;
2387
+ position: absolute;
2388
+ }
2389
+ }
2390
+
2391
+ /* Text */
2392
+ .text {
2393
+ flex: 1;
2394
+ line-height: 1.6;
2395
+
2396
+ :where(h1, h2, h3, h4, h5, h6, p, span) {
2397
+ color: inherit;
2398
+ font-weight: 400;
2399
+ }
2400
+
2401
+ p + p {
2402
+ font-size: var(--font-size-xs);
2403
+ }
2404
+ }
2405
+
2406
+ /* Leading content */
2407
+ .start {
2408
+ align-self: center;
2409
+ align-items: center;
2410
+ display: grid;
2411
+ z-index: 1;
2412
+
2413
+ &:has(svg) {
2414
+ max-inline-size: var(--size-5);
2415
+ }
2416
+
2417
+ svg {
2418
+ padding-block-start: 0.125rem;
2419
+ }
2420
+
2421
+ img {
2422
+ aspect-ratio: 1;
2423
+ inline-size: 56px;
2424
+ object-fit: cover;
2425
+ }
2426
+
2427
+ video {
2428
+ aspect-ratio: 16/9;
2429
+ block-size: 64px;
2430
+ object-fit: cover;
2431
+ }
2432
+ }
2433
+
2434
+ /* Trailing content */
2435
+ .end {
2436
+ align-items: center;
2437
+ display: flex;
2438
+ font-size: var(--font-size-xs);
2439
+ text-align: end;
2440
+ z-index: 1;
2441
+
2442
+ &:not(:has(a, button, input)) {
2443
+ pointer-events: none;
2444
+ }
2445
+
2446
+ kbd {
2447
+ background-color: transparent;
2448
+ border: 0;
2449
+ color: inherit;
2450
+ opacity: 0.6;
2451
+ }
2452
+
2453
+ svg {
2454
+ max-inline-size: var(--size-5);
2455
+ inline-size: 100%;
2456
+ }
2457
+ }
2458
+
2459
+ /* Inset */
2460
+ &.inset {
2461
+ .text {
2462
+ padding-inline-start: calc(var(--size-5) + var(--size-3));
2463
+ }
2464
+
2465
+ /* Safety measure so it won't look bad if there for some reason should exist a leading element inside. */
2466
+ .start {
2467
+ display: none;
2468
+ }
2469
+ }
2470
+ }
2471
+ }
2472
+ }
2473
+
2474
+ @layer components.extended {
2475
+ :where(.alert) {
2476
+ --_bg-color: var(--surface-tonal);
2477
+ --_border-color: var(--surface-tonal);
2478
+ --_color: var(--text-color-1);
2479
+
2480
+ &.outlined {
2481
+ --_bg-color: var(--surface-default);
2482
+ --_border-color: var(--border-color);
2483
+ --_color: var(--text-color-1);
2484
+ }
2485
+
2486
+ background-color: var(--_bg-color);
2487
+ border: 1px solid var(--_border-color);
2488
+ border-radius: var(--border-radius);
2489
+ color: var(--_color);
2490
+ padding: var(--size-3);
2491
+
2492
+ & > .content {
2493
+ display: grid;
2494
+ gap: var(--size-2);
2495
+ font-size: var(--font-size-sm);
2496
+
2497
+ h1,
2498
+ h2,
2499
+ h3,
2500
+ h4,
2501
+ h5,
2502
+ h6 {
2503
+ color: inherit;
2504
+ font-size: var(--font-size-md);
2505
+ font-weight: 600;
2506
+
2507
+ * {
2508
+ font-size: inherit;
2509
+ }
2510
+ }
2511
+ }
2512
+
2513
+ /* Colors */
2514
+ &.error,
2515
+ &.ok,
2516
+ &.warning {
2517
+ --_bg-color: var(--color-4);
2518
+ --_border-color: var(--color-9);
2519
+ --_color: var(--color-15);
2520
+
2521
+ &.outlined {
2522
+ --_bg-color: var(--surface-default);
2523
+ --_border-color: var(--color-9);
2524
+ --_color: light-dark(var(--color-15), var(--color-1));
2525
+ }
2526
+
2527
+ svg {
2528
+ margin-block-start: 0.15rem;
2529
+ stroke: var(--color-9);
2530
+ }
2531
+ }
2532
+
2533
+ /* Links
2534
+ * Can't make sure contrast will be acceptable (yet) so we use the current text color instead.
2535
+ */
2536
+ &:not(.outlined) {
2537
+ a[href] {
2538
+ color: inherit;
2539
+
2540
+ &:hover {
2541
+ color: var(--primary);
2542
+ }
2543
+ }
2544
+ }
2545
+
2546
+ /* Icon */
2547
+ &:has(svg) {
2548
+ display: grid;
2549
+ gap: var(--size-3);
2550
+ grid-template-columns: var(--size-4) 1fr;
2551
+
2552
+ svg {
2553
+ margin-block-start: 0.15rem;
2554
+ stroke: currentColor;
2555
+ }
2556
+ }
2557
+ }
2558
+ }
2559
+
2560
+ @layer components.extended {
2561
+ :where(dialog) {
2562
+ margin-block-start: 15%; /* vertical alignment */
2563
+ padding-block: 0;
2564
+ pointer-events: none;
2565
+
2566
+ &::backdrop {
2567
+ background-color: rgba(0, 0, 0, 0.5);
2568
+ backdrop-filter: blur(5px);
2569
+
2570
+ @media (prefers-reduced-motion: reduce) {
2571
+ backdrop-filter: none;
2572
+ }
2573
+ }
2574
+
2575
+ &:not([open]) {
2576
+ display: none;
2577
+ }
2578
+
2579
+ &[open] {
2580
+ pointer-events: all;
2581
+ }
2582
+
2583
+ .actions {
2584
+ justify-content: end;
2585
+ padding-inline: var(--size-3) var(--size-1);
2586
+ }
2587
+
2588
+ /* Animation */
2589
+ /* There's no close animation, intentionally */
2590
+ opacity: 0;
2591
+
2592
+ &[open] {
2593
+ opacity: 1;
2594
+ transition: display 0.2s allow-discrete,
2595
+ margin-block-start 0.3s var(--ease-1), overlay 0.2s allow-discrete,
2596
+ opacity 0.2s var(--ease-out-1);
2597
+
2598
+ @starting-style {
2599
+ opacity: 0;
2600
+ }
2601
+ }
2602
+
2603
+ @media (prefers-reduced-motion: no-preference) {
2604
+ margin-block-start: 17%;
2605
+ &[open] {
2606
+ margin-block-start: 15%;
2607
+
2608
+ @starting-style {
2609
+ margin-block-start: 17%;
2610
+ }
2611
+ }
2612
+ }
2613
+ }
2614
+
2615
+ :where(html:has(dialog[open])) {
2616
+ overflow: hidden;
2617
+ }
2618
+ }
2619
+
2620
+ @layer components.extended {
2621
+ :where(.snackbar) {
2622
+ align-items: center;
2623
+ /* Inverse surface-filled */
2624
+ background-color: light-dark(var(--gray-15), var(--gray-2));
2625
+ border-radius: var(--border-radius);
2626
+ box-shadow: var(--shadow-2);
2627
+ color: var(--text-color-1-contrast);
2628
+ display: flex;
2629
+ font-size: var(--font-size-sm);
2630
+ gap: var(--size-3);
2631
+ inset-block: auto var(--size-3);
2632
+ inset-inline: var(--size-3) auto;
2633
+ justify-content: space-between;
2634
+ min-inline-size: min(100%, 37ch);
2635
+ padding: var(--size-2) var(--size-3);
2636
+ position: fixed;
2637
+ inline-size: calc(100% - var(--size-6, 1.75rem));
2638
+ z-index: 100;
2639
+
2640
+ &::backdrop {
2641
+ display: none;
2642
+ }
2643
+
2644
+ * {
2645
+ word-break: break-word;
2646
+ }
2647
+
2648
+ /* Global positioning (in relation to the window) */
2649
+ /*** Default (end-start) */
2650
+ inset-block: auto var(--size-3);
2651
+ inset-inline: 50% 0;
2652
+ translate: -50% 0;
2653
+
2654
+ &.start-start,
2655
+ &.start-center,
2656
+ &.start-end {
2657
+ inset-block: var(--size-3) auto;
2658
+ }
2659
+
2660
+ /* TODO use @custom-media instead? */
2661
+ @container (width > 480px) {
2662
+ /* Default (end-start) */
2663
+ inset-block: auto var(--size-7, 2rem);
2664
+ inset-inline: var(--size-7, 2rem) auto;
2665
+ translate: revert;
2666
+ inline-size: fit-content;
2667
+
2668
+ &.end-start,
2669
+ &.end-end,
2670
+ &.start-start,
2671
+ &.start-end {
2672
+ translate: revert;
2673
+ }
2674
+
2675
+ &.start-start {
2676
+ inset-block: var(--size-7, 2rem) auto;
2677
+ inset-inline: var(--size-7, 2rem) auto;
2678
+ }
2679
+ &.start-center {
2680
+ inset-block: var(--size-7, 2rem) auto;
2681
+ inset-inline: 50% 0;
2682
+ translate: -50% 0;
2683
+ }
2684
+ &.start-end {
2685
+ inset-block: var(--size-7, 2rem) auto;
2686
+ inset-inline: auto var(--size-7, 2rem);
2687
+ }
2688
+ &.end-start {
2689
+ inset-block-end: var(--size-7, 2rem);
2690
+ inset-inline: var(--size-7, 2rem) auto;
2691
+ }
2692
+ &.end-center {
2693
+ inset-block: auto var(--size-7, 2rem);
2694
+ inset-inline: 50% 0;
2695
+ translate: -50% 0;
2696
+ }
2697
+ &.end-end {
2698
+ inset-block: auto var(--size-7, 2rem);
2699
+ inset-inline: auto var(--size-7, 2rem);
2700
+ }
2701
+ }
2702
+
2703
+ /* Absolute positioning */
2704
+ &.absolute {
2705
+ position: absolute;
2706
+ }
2707
+
2708
+ /* Actions */
2709
+ .actions {
2710
+ align-items: center;
2711
+ display: flex;
2712
+ flex-shrink: 0;
2713
+ gap: var(--size-3);
2714
+ padding-inline: 0;
2715
+
2716
+ button {
2717
+ /* Inverse hover and active backgrounds */
2718
+ &:where(:not([disabled])) {
2719
+ &:where(:not(:active):hover) {
2720
+ --_bg-color: light-dark(
2721
+ color-mix(in oklch, white 40%, black),
2722
+ color-mix(in oklch, white 85%, black)
2723
+ );
2724
+ }
2725
+
2726
+ &:where(:hover:active) {
2727
+ --_bg-color: light-dark(
2728
+ color-mix(in oklch, white 45%, black),
2729
+ color-mix(in oklch, white 80%, black)
2730
+ );
2731
+ }
2732
+ }
2733
+ }
2734
+
2735
+ button:not(:has(svg)) {
2736
+ border-radius: var(--border-radius);
2737
+ font-size: inherit;
2738
+ max-block-size: var(--size-6, 1.5rem);
2739
+ padding: 1ex;
2740
+ }
2741
+
2742
+ button:has(svg) {
2743
+ color: inherit;
2744
+ max-inline-size: var(--size-6, 1.75rem);
2745
+ margin: var(--size-00);
2746
+ padding: var(--size-1);
2747
+ }
2748
+ }
2749
+
2750
+ /* Animations */
2751
+ opacity: 0;
2752
+ transition: display 0.075s allow-discrete, overlay 0.075s allow-discrete,
2753
+ opacity 0.075s var(--ease-out-1);
2754
+
2755
+ &:popover-open,
2756
+ &:popover-open::backdrop,
2757
+ &.visible {
2758
+ opacity: 1;
2759
+ transition: display 0.25s allow-discrete, overlay 0.25s allow-discrete,
2760
+ opacity 0.25s var(--ease-out-1);
2761
+
2762
+ @starting-style {
2763
+ opacity: 0;
2764
+ }
2765
+ }
2766
+ }
2767
+ }
2768
+
2769
+ @layer components.extended {
2770
+ /* Common styling for checkbox, radio and switch groups */
2771
+ :where(fieldset.field-group) {
2772
+ border: 0;
2773
+ border-radius: 0;
2774
+ gap: 0;
2775
+ padding: 0;
2776
+ z-index: 1;
2777
+
2778
+ legend {
2779
+ color: var(--text-color-2);
2780
+ padding: 0 1ex 0 0;
2781
+ }
2782
+
2783
+ /* Disabled */
2784
+ &[disabled] {
2785
+ cursor: not-allowed;
2786
+ opacity: 0.64;
2787
+ user-select: none;
2788
+
2789
+ input {
2790
+ cursor: not-allowed;
2791
+ }
2792
+ }
2793
+
2794
+ /* Validation */
2795
+ &.error {
2796
+ legend,
2797
+ .supporting-text {
2798
+ color: var(--color-9);
2799
+ }
2800
+ }
2801
+
2802
+ /* Required */
2803
+ &:has([required]) {
2804
+ &:not(:has(input:where([type="radio"], [type="checkbox"]):checked)) {
2805
+ legend {
2806
+ position: relative;
2807
+
2808
+ &::after {
2809
+ color: var(--red);
2810
+ content: "*";
2811
+ inset: 0 -0.25ex auto auto;
2812
+ position: absolute;
2813
+ }
2814
+ }
2815
+ }
2816
+ }
2817
+ :where(.radio, .checkbox, .switch) .label:after {
2818
+ display: none;
2819
+ }
2820
+
2821
+ /* Supporting text */
2822
+ .supporting-text {
2823
+ color: var(--text-color-2);
2824
+ font-size: var(--font-size-xs);
2825
+ line-height: 1.5;
2826
+ z-index: 1;
2827
+ }
2828
+
2829
+ /* Fields */
2830
+ .fields {
2831
+ display: flex;
2832
+ flex-direction: column;
2833
+ gap: var(--size-2);
2834
+
2835
+ * ~ & {
2836
+ padding: var(--size-2) 0;
2837
+ }
2838
+ }
2839
+
2840
+ :last-child {
2841
+ padding-block-end: 0;
2842
+ }
2843
+
2844
+ /* Directions */
2845
+ &.row {
2846
+ .fields {
2847
+ flex-direction: row;
2848
+ }
2849
+ }
2850
+ }
2851
+ }
2852
+
2853
+ @layer components.extended {
2854
+ /*
2855
+ - Common styling for input, textarea and select
2856
+ - Form related styles such as: label, supporting text, error handling
2857
+ */
2858
+ :where(.field) {
2859
+ --_accent-color: var(--primary);
2860
+ --_bg-color: var(--surface-default);
2861
+ --_border-color: var(--field-border-color);
2862
+ --_field-padding-block: 0.75rem;
2863
+ --_field-padding-inline: var(--size-2);
2864
+ --_filled-border-color: var(--text-color-1);
2865
+ --_height: var(--field-size);
2866
+ --_label-color: var(--text-color-2);
2867
+ --_supporting-text-color: var(--text-color-2);
2868
+
2869
+ display: grid;
2870
+ position: relative;
2871
+
2872
+ /* Input/Select base */
2873
+ :where(& input, & textarea, & select) {
2874
+ background-color: var(--_bg-color);
2875
+ block-size: var(--_height);
2876
+ border-radius: var(--field-border-radius);
2877
+ border: var(--field-border-width) solid var(--_border-color);
2878
+ color: var(--text-color-1);
2879
+ font-family: var(--font-sans);
2880
+ font-size: var(--font-size-1);
2881
+ grid-column: 1/-1;
2882
+ grid-row: 2;
2883
+ inline-size: 100%;
2884
+ line-height: var(--font-lineheight-1);
2885
+ min-inline-size: 0;
2886
+ padding: var(--_field-padding-block) var(--_field-padding-inline);
2887
+
2888
+ @media (prefers-reduced-motion: no-preference) {
2889
+ transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
2890
+ padding-block 0.2s var(--ease-3);
2891
+ }
2892
+ }
2893
+
2894
+ /* Required/Invalid */
2895
+ &:has(
2896
+ :not(:placeholder-shown):invalid,
2897
+ :where(
2898
+ :placeholder-shown,
2899
+ option[value=""]:not(:checked),
2900
+ option:checked:not([value=""])
2901
+ ):required
2902
+ ) {
2903
+ .label:after {
2904
+ color: var(--red);
2905
+ content: "*";
2906
+ margin: -0.25em auto auto 0.25em;
2907
+ }
2908
+ }
2909
+
2910
+ /* File */
2911
+ &:has(input[type="file"]) {
2912
+ cursor: pointer;
2913
+
2914
+ input {
2915
+ align-self: flex-start;
2916
+ block-size: var(--_height);
2917
+ box-shadow: none;
2918
+ color: var(--text-color-1);
2919
+ cursor: inherit;
2920
+ max-inline-size: 100%;
2921
+ padding: 0;
2922
+ transition: font-size 0.2s var(--ease-3);
2923
+
2924
+ &::-webkit-file-upload-button,
2925
+ &::file-selector-button {
2926
+ background-color: var(--surface-tonal);
2927
+ border: none;
2928
+ block-size: calc(100% - var(--size-2) * 2);
2929
+ border-radius: var(--field-border-radius);
2930
+ cursor: pointer;
2931
+ margin-inline-end: 1ex;
2932
+ margin-block-start: var(--size-2);
2933
+ margin-inline-start: var(--size-2);
2934
+ }
2935
+ }
2936
+
2937
+ /* Variants */
2938
+ &.filled {
2939
+ input {
2940
+ &::-webkit-file-upload-button,
2941
+ &::file-selector-button {
2942
+ background-color: var(--surface-default);
2943
+ block-size: calc(100% - var(--size-2) * 2);
2944
+ border-radius: var(--field-border-radius);
2945
+ cursor: pointer;
2946
+ margin-block-start: var(--size-2);
2947
+ }
2948
+ }
2949
+ }
2950
+
2951
+ /* Sizes */
2952
+ &.small {
2953
+ input {
2954
+ font-size: var(--font-size-sm);
2955
+ &::-webkit-file-upload-button,
2956
+ &::file-selector-button {
2957
+ block-size: calc(100% - var(--size-2));
2958
+ margin-block-start: var(--size-1);
2959
+ }
2960
+ }
2961
+ }
2962
+ }
2963
+
2964
+ /* Autosuggest */
2965
+ &:has(input[list]) {
2966
+ .label {
2967
+ /* Make sure chevron is visible */
2968
+ inline-size: calc(100% - var(--size-6));
2969
+ }
2970
+ }
2971
+
2972
+ /* Select */
2973
+ &:has(select) {
2974
+ .label {
2975
+ /* Make sure chevron is visible */
2976
+ inline-size: calc(100% - var(--size-6));
2977
+ }
2978
+ }
2979
+
2980
+ /* Experimental Select */
2981
+ &:has(select button) {
2982
+ select {
2983
+ padding: 0;
2984
+
2985
+ button {
2986
+ outline: 0;
2987
+ padding: var(--_field-padding-block) var(--size-8)
2988
+ var(--_field-padding-block) var(--_field-padding-inline);
2989
+ }
2990
+ }
2991
+ }
2992
+
2993
+ /* Non-experimental Select */
2994
+ &:has(select):not(:has(button)) {
2995
+ select {
2996
+ padding: var(--_field-padding-block) var(--size-8)
2997
+ var(--_field-padding-block) var(--_field-padding-inline);
2998
+ }
2999
+ }
3000
+
3001
+ /* Input - color */
3002
+ &:has(input[type="color"]) {
3003
+ input {
3004
+ appearance: none;
3005
+ background: none;
3006
+ block-size: var(--_height);
3007
+ inline-size: var(--_height);
3008
+ overflow: hidden;
3009
+ padding: 0;
3010
+
3011
+ &::-webkit-color-swatch {
3012
+ border: none;
3013
+ }
3014
+
3015
+ &::-webkit-color-swatch-wrapper {
3016
+ padding: 0;
3017
+ }
3018
+ }
3019
+ }
3020
+
3021
+ /* Element states */
3022
+ &:hover {
3023
+ &:not(.error) {
3024
+ :where(input, textarea, select) {
3025
+ --_border-color: var(--text-color-1);
3026
+ }
3027
+ }
3028
+ }
3029
+
3030
+ &:focus-within {
3031
+ & input,
3032
+ & textarea,
3033
+ & select {
3034
+ border-color: var(--_accent-color);
3035
+ outline-offset: -2px;
3036
+ outline: 2px solid var(--_accent-color);
3037
+ }
3038
+ }
3039
+
3040
+ /* Label */
3041
+ .label {
3042
+ font-size: var(--font-size-sm);
3043
+ grid-column: 1/-1;
3044
+ grid-row: 1;
3045
+ }
3046
+
3047
+ /* Supporting text */
3048
+ .supporting-text {
3049
+ color: var(--_supporting-text-color);
3050
+ font-size: var(--font-size-xs);
3051
+ grid-column: 1/-1;
3052
+ grid-row: 3;
3053
+ line-height: 1.5;
3054
+ }
3055
+
3056
+ /* Auto-fit */
3057
+ &.auto-fit {
3058
+ inline-size: auto;
3059
+
3060
+ :where(& input, & textarea) {
3061
+ field-sizing: content;
3062
+ inline-size: auto;
3063
+ }
3064
+ }
3065
+
3066
+ /* Validation */
3067
+ &.error {
3068
+ --_accent-color: var(--color-9);
3069
+ --_border-color: var(--color-9);
3070
+ --_filled-border-color: var(--color-9);
3071
+ --_label-color: var(--color-9);
3072
+ --_supporting-text-color: var(--color-9);
3073
+ }
3074
+
3075
+ /*
3076
+ * Variant: Filled
3077
+ */
3078
+ &.filled {
3079
+ --_bg-color: var(--surface-tonal);
3080
+
3081
+ &:not(:has([disabled], :has(input[type="color"]))) {
3082
+ /* Hover */
3083
+ &:hover {
3084
+ --_bg-color: light-dark(
3085
+ oklch(from var(--surface-tonal) calc(l * 0.93) c h),
3086
+ oklch(from var(--surface-tonal) calc(l * 1.1) c h)
3087
+ );
3088
+ }
3089
+ }
3090
+ }
3091
+
3092
+ /* Disabled */
3093
+ &:where(:has([disabled])) {
3094
+ &::before {
3095
+ display: none;
3096
+ }
3097
+ :where(input, textarea, select) {
3098
+ cursor: not-allowed;
3099
+ opacity: 0.7;
3100
+
3101
+ * {
3102
+ pointer-events: none;
3103
+ }
3104
+ }
3105
+ }
3106
+
3107
+ /* Read-only */
3108
+ &:where(:has([readonly])) {
3109
+ &::before {
3110
+ display: none;
3111
+ }
3112
+ :where(input, textarea, select) {
3113
+ cursor: not-allowed;
3114
+
3115
+ * {
3116
+ pointer-events: none;
3117
+ }
3118
+ }
3119
+ }
3120
+
3121
+ /* Sizes */
3122
+ &.small {
3123
+ --_field-padding-block: var(--size-2);
3124
+ --_height: var(--field-size-small);
3125
+
3126
+ &:has(input[type="color"]) {
3127
+ .label {
3128
+ line-height: 1.5;
3129
+ }
3130
+ }
3131
+ }
3132
+ }
3133
+ }
3134
+
3135
+ @layer components.extended {
3136
+ :where(.field > select) {
3137
+ position: relative;
3138
+
3139
+ /* Default arrow */
3140
+ &::picker-icon {
3141
+ block-size: 0;
3142
+ border-block-start: 5px solid;
3143
+ border-inline: 5px solid transparent;
3144
+ color: currentColor;
3145
+ content: "";
3146
+ inline-size: 0;
3147
+ inset: 50% var(--size-3) auto auto;
3148
+ pointer-events: none;
3149
+ position: absolute;
3150
+ translate: 0 -50%;
3151
+ }
3152
+
3153
+ &:open {
3154
+ &::picker-icon {
3155
+ rotate: 180deg;
3156
+ }
3157
+ }
3158
+
3159
+ /* Select popover */
3160
+ &::picker(select) {
3161
+ /* Animation on-stage styles */
3162
+ border: 0;
3163
+ box-shadow: var(--shadow-2);
3164
+ opacity: 1;
3165
+ padding: 0;
3166
+ scale: 1;
3167
+
3168
+ /* Animation starting styles */
3169
+ @starting-style {
3170
+ opacity: 0;
3171
+ transform: scale(0.9);
3172
+ }
3173
+
3174
+ @media (prefers-reduced-motion: no-preference) {
3175
+ transition: display 0.2s allow-discrete, opacity 0.2s var(--ease-3),
3176
+ overlay 0.2s allow-discrete, scale 0.2s var(--ease-3);
3177
+ }
3178
+ }
3179
+
3180
+ /* Animation off-stage styles */
3181
+ &:not(:open)::picker(select) {
3182
+ opacity: 0;
3183
+ scale: 0.9;
3184
+ }
3185
+
3186
+ button {
3187
+ background-color: transparent;
3188
+ display: flex;
3189
+ inline-size: 100%;
3190
+ margin: 0;
3191
+ position: relative;
3192
+
3193
+ selectedcontent {
3194
+ overflow: hidden;
3195
+ text-overflow: ellipsis;
3196
+ white-space: nowrap;
3197
+ }
3198
+ }
3199
+
3200
+ .list {
3201
+ /* Groups */
3202
+ [role="group"] {
3203
+ label {
3204
+ background-color: light-dark(var(--gray-3), var(--gray-13));
3205
+ color: light-dark(
3206
+ oklch(from var(--text-color-1) calc(l * 0.75) c h),
3207
+ oklch(from var(--text-color-1) calc(l * 1.25) c h)
3208
+ );
3209
+ font-weight: 500;
3210
+ overflow: hidden;
3211
+ padding-inline: var(--size-2);
3212
+ text-overflow: ellipsis;
3213
+ white-space: nowrap;
3214
+ }
3215
+
3216
+ &:not(:first-child),
3217
+ option:first-of-type {
3218
+ margin-block-start: var(--size-2);
3219
+ }
3220
+
3221
+ option:last-of-type,
3222
+ &:last-child {
3223
+ option:last-of-type {
3224
+ margin-block-end: 0;
3225
+ }
3226
+ }
3227
+ }
3228
+
3229
+ /* Option */
3230
+ option {
3231
+ /* Checkmark */
3232
+ /* TODO - checkmark should be the final version of the checkmark API. Follow the development of this and remove redundant psuedo stuff. */
3233
+ &::check {
3234
+ display: none;
3235
+ }
3236
+ &::checkmark {
3237
+ display: none;
3238
+ }
3239
+ &::before {
3240
+ display: none;
3241
+ }
3242
+
3243
+ &:focus-visible {
3244
+ outline-offset: -1px;
3245
+ }
3246
+ }
3247
+ }
3248
+ }
3249
+
3250
+ :where(.field:has(> select)) {
3251
+ /* Size */
3252
+ &.small {
3253
+ button {
3254
+ padding-inline: var(--size-2) var(--size-7);
3255
+
3256
+ &::after {
3257
+ inset-inline-end: var(--size-2);
3258
+ }
3259
+ }
3260
+ }
3261
+
3262
+ /*
3263
+ * Non-experimental Select
3264
+ *
3265
+ * Hack to get the arrow working. Pseudo elements aren't allowed on the `<select>` element, so need to add it on the `.field` class instead. Noting this down if an `:after` element would be needed on a `.field`.
3266
+ */
3267
+ &:not(:has(button)) {
3268
+ select {
3269
+ appearance: none;
3270
+ }
3271
+
3272
+ /* Arrow */
3273
+ &::after {
3274
+ align-self: center;
3275
+ block-size: 0;
3276
+ border-block-start: 5px solid;
3277
+ border-inline: 5px solid transparent;
3278
+ content: "";
3279
+ display: inline-block;
3280
+ flex-shrink: 0;
3281
+ grid-column: 1/-1;
3282
+ grid-row: 2;
3283
+ inline-size: 0;
3284
+ inset-inline-end: var(--size-3);
3285
+ justify-self: end;
3286
+ pointer-events: none;
3287
+ position: relative;
3288
+ }
3289
+ }
3290
+ }
3291
+
3292
+ select:has(button),
3293
+ ::picker(select) {
3294
+ appearance: base-select;
3295
+ }
3296
+ }
3297
+
3298
+ @layer components.extended {
3299
+ :where(
3300
+ .field:has(
3301
+ :where(
3302
+ input[type="date"],
3303
+ input[type="datetime-local"],
3304
+ input[type="email"],
3305
+ input[type="month"],
3306
+ input[type="number"],
3307
+ input[type="password"],
3308
+ input[type="search"],
3309
+ input[type="tel"],
3310
+ input[type="text"],
3311
+ input[type="time"],
3312
+ input[type="url"],
3313
+ input[type="week"]
3314
+ )
3315
+ )
3316
+ ) {
3317
+ /* Sizes */
3318
+ &.small {
3319
+ input {
3320
+ padding-inline: var(--size-2);
3321
+ }
3322
+ }
3323
+ }
3324
+
3325
+ /* Autosuggest */
3326
+ :where(.field:has(input[list])) {
3327
+ /* Hide native arrow */
3328
+ input::-webkit-calendar-picker-indicator {
3329
+ opacity: 0;
3330
+ position: absolute;
3331
+ cursor: pointer;
3332
+ pointer-events: none;
3333
+ }
3334
+ }
3335
+ :where(
3336
+ .field:has(input[list]:placeholder-shown),
3337
+ .field:has(input[list]):where(:focus-within, :hover)
3338
+ ) {
3339
+ /* Arrow */
3340
+ &::after {
3341
+ block-size: 0;
3342
+ border-block-start: 5px solid;
3343
+ border-inline: 5px solid transparent;
3344
+ content: "";
3345
+ display: inline-block;
3346
+ flex-shrink: 0;
3347
+ inline-size: 0;
3348
+ inset: 50% var(--size-3) auto auto;
3349
+ pointer-events: none;
3350
+ position: absolute;
3351
+ translate: 0 -50%;
3352
+ }
3353
+ }
3354
+ }
3355
+
3356
+ @layer components.extended {
3357
+ :where(.field:has(textarea)) {
3358
+ textarea {
3359
+ block-size: auto;
3360
+ field-sizing: content;
3361
+ min-block-size: 5rem;
3362
+ resize: vertical;
3363
+ }
3364
+
3365
+ /* Size */
3366
+ &.small {
3367
+ textarea {
3368
+ min-block-size: var(--_height);
3369
+ }
3370
+ }
3371
+
3372
+ /* Auto-fit */
3373
+ &.auto-fit {
3374
+ textarea {
3375
+ min-block-size: var(--_height);
3376
+ resize: both;
3377
+ }
3378
+ }
3379
+ }
3380
+ }
3381
+
3382
+ @layer components.extended {
3383
+ @scope (.rich-text) to (.not-rich-text) {
3384
+ a {
3385
+ color: var(--primary);
3386
+ cursor: pointer;
3387
+ font-size: inherit;
3388
+ font-weight: 700;
3389
+ line-height: inherit;
3390
+ text-decoration: underline;
3391
+ text-decoration-color: var(--primary);
3392
+ text-underline-offset: 2px;
3393
+
3394
+ &[href] {
3395
+ &:hover,
3396
+ &:focus-visible {
3397
+ color: var(--primary-light);
3398
+ }
3399
+ }
3400
+ }
3401
+
3402
+ /* Blockquote */
3403
+ blockquote {
3404
+ font-size: inherit;
3405
+ line-height: inherit;
3406
+ :first-child {
3407
+ margin-block-start: 0;
3408
+ }
3409
+
3410
+ :last-child {
3411
+ margin-block-end: 0;
3412
+ }
3413
+ }
3414
+
3415
+ /* Text */
3416
+ p {
3417
+ font-size: inherit;
3418
+ line-height: inherit;
3419
+ margin-block: 1.25em;
3420
+ }
3421
+
3422
+ :is(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
3423
+ color: var(--text-color-1);
3424
+
3425
+ & + *:not(&) {
3426
+ margin-block-start: 0;
3427
+ }
3428
+ }
3429
+
3430
+ h1,
3431
+ .h1 {
3432
+ font-size: var(--font-size-h1, var(--font-size-7));
3433
+ letter-spacing: -0.02em;
3434
+ line-height: 1.1111111;
3435
+ margin-block: 0 0.8888889em;
3436
+ }
3437
+
3438
+ h2,
3439
+ .h2 {
3440
+ font-size: var(--font-size-h2, var(--font-size-5, 2rem));
3441
+ letter-spacing: -0.02em;
3442
+ line-height: 1.3333333;
3443
+ margin-block: 2em 1em;
3444
+ }
3445
+
3446
+ h3,
3447
+ .h3 {
3448
+ font-size: var(--font-size-h3, var(--font-size-4, 1.5rem));
3449
+ letter-spacing: -0.01em;
3450
+ line-height: 1.6;
3451
+ margin-block: 1.6em 0.6em;
3452
+ }
3453
+
3454
+ h4,
3455
+ .h4 {
3456
+ font-size: var(--font-size-h4, var(--font-size-3, 1.25rem));
3457
+ letter-spacing: -0.01em;
3458
+ line-height: 1.5;
3459
+ margin-block: 1.5em 0.5em;
3460
+ }
3461
+
3462
+ h5,
3463
+ .h5 {
3464
+ font-size: var(--font-size-h5, var(--font-size-2, 1.1rem));
3465
+ line-height: 1;
3466
+ margin-block: 0 var(--size-1);
3467
+ }
3468
+
3469
+ h6,
3470
+ .h6 {
3471
+ font-size: var(--font-size-h6, var(--font-size-1, 1rem));
3472
+ line-height: 1;
3473
+ margin-block: 0 var(--size-1);
3474
+ }
3475
+
3476
+ /** Overline */
3477
+ :where(.overline, hgroup > :where(p, .p):first-of-type:first-child) {
3478
+ color: light-dark(
3479
+ oklch(from var(--text-color-2) calc(l * 1.25) c h),
3480
+ oklch(from var(--text-color-2) calc(l * 0.75) c h)
3481
+ );
3482
+ font-size: var(--font-size-xs);
3483
+ font-weight: 500;
3484
+ letter-spacing: 0.06em;
3485
+ line-height: 2.5;
3486
+ text-transform: uppercase;
3487
+ }
3488
+
3489
+ hgroup {
3490
+ & > p {
3491
+ margin: 0;
3492
+ }
3493
+
3494
+ & > :where(h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6) {
3495
+ margin-block-end: 0.4em;
3496
+ }
3497
+
3498
+ & + * {
3499
+ margin-block-start: 3em;
3500
+ }
3501
+
3502
+ /* The second p element */
3503
+ & > :where(p, .p):last-of-type:last-child:not(:first-child) {
3504
+ color: oklch(from currentColor l c h / 75%);
3505
+ font-size: var(--font-size-lg);
3506
+ line-height: 1.6;
3507
+ }
3508
+ }
3509
+
3510
+ /* Lists */
3511
+ ul:not([class]) {
3512
+ list-style-type: disc;
3513
+ }
3514
+
3515
+ ol:not([class]) {
3516
+ list-style-type: decimal;
3517
+ }
3518
+
3519
+ :where(ul, ol):not([class]) {
3520
+ display: grid;
3521
+ font-size: inherit;
3522
+ gap: 0.5em;
3523
+ line-height: inherit;
3524
+ margin-block-start: 1.25em;
3525
+ margin-block-end: 1.25em;
3526
+ padding-inline-start: 1.625em;
3527
+
3528
+ li {
3529
+ padding-inline-start: 0.375em;
3530
+ }
3531
+ }
3532
+
3533
+ /* Nested lists */
3534
+ :where(ul ul),
3535
+ :where(ul ol),
3536
+ :where(ol ul),
3537
+ :where(ol ol) {
3538
+ margin-block-start: 0.75em;
3539
+ margin-block-end: 0.75em;
3540
+ }
3541
+
3542
+ /* Description lists */
3543
+ :where(dl) {
3544
+ font-size: inherit;
3545
+ line-height: inherit;
3546
+ margin-block-start: 1.25em;
3547
+ margin-block-end: 1.25em;
3548
+
3549
+ dt {
3550
+ margin-block-start: 1.25em;
3551
+ }
3552
+
3553
+ dd {
3554
+ margin-block-start: 0.5em;
3555
+ padding-inline-start: 1.625em;
3556
+ }
3557
+ }
3558
+
3559
+ /* Figures */
3560
+ figure {
3561
+ margin-block: 2em;
3562
+
3563
+ & > * {
3564
+ margin-block: 0;
3565
+ }
3566
+
3567
+ & figcaption {
3568
+ font-size: 0.875em;
3569
+ line-height: 1.4285714;
3570
+ margin-block-start: 0.8571429em;
3571
+ }
3572
+ }
3573
+
3574
+ /* Remove top margin from first child */
3575
+ & > :first-child {
3576
+ margin-block-start: 0;
3577
+ }
3578
+
3579
+ /* Remove bottom margin from last child */
3580
+ & > :last-child {
3581
+ margin-block-end: 0;
3582
+ }
3583
+
3584
+ /* Horizontal rules */
3585
+ hr {
3586
+ & + * {
3587
+ margin-block-start: 0;
3588
+ }
3589
+ }
3590
+ }
3591
+ }