opui-css 3.3.4 → 4.0.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 (174) hide show
  1. package/CHANGELOG.md +235 -0
  2. package/LICENSE +21 -21
  3. package/MIGRATING.md +105 -0
  4. package/README.md +66 -29
  5. package/astro/index.ts +46 -0
  6. package/components/AGENTS.md +247 -0
  7. package/components/Accordion/Accordion.astro +42 -0
  8. package/components/Anchor/Anchor.astro +51 -0
  9. package/components/Avatar/Avatar.astro +44 -0
  10. package/components/Badge/Badge.astro +54 -0
  11. package/components/Button/Button.astro +45 -0
  12. package/components/ButtonGroup/ButtonGroup.astro +29 -0
  13. package/components/Callout/Callout.astro +75 -0
  14. package/components/Card/Card.astro +38 -0
  15. package/components/Checkbox/Checkbox.astro +76 -0
  16. package/components/Checkbox/CheckboxInput.astro +32 -0
  17. package/components/Chip/Chip.astro +37 -0
  18. package/components/ClassicSelect/ClassicSelect.astro +83 -0
  19. package/components/DescriptionList/Description.astro +12 -0
  20. package/components/DescriptionList/DescriptionList.astro +22 -0
  21. package/components/DescriptionList/Item.astro +12 -0
  22. package/components/DescriptionList/Term.astro +12 -0
  23. package/components/DescriptionList/index.ts +12 -0
  24. package/components/Dialog/Dialog.astro +43 -0
  25. package/components/Divider/Divider.astro +14 -0
  26. package/components/Drawer/Drawer.astro +49 -0
  27. package/components/Drawer/DrawerFooter.astro +14 -0
  28. package/components/Drawer/DrawerHeader.astro +31 -0
  29. package/components/FieldDescription/FieldDescription.astro +13 -0
  30. package/components/FieldGroup/FieldGroup.astro +31 -0
  31. package/components/FieldLegend/FieldLegend.astro +15 -0
  32. package/components/FieldSet/FieldSet.astro +15 -0
  33. package/components/Form/Form.astro +15 -0
  34. package/components/IconButton/IconButton.astro +26 -0
  35. package/components/List/List.astro +36 -0
  36. package/components/ListItem/ListItem.astro +118 -0
  37. package/components/Progress/Progress.astro +40 -0
  38. package/components/Radio/Radio.astro +70 -0
  39. package/components/Radio/RadioInput.astro +24 -0
  40. package/components/Range/Range.astro +136 -0
  41. package/components/Select/Select.astro +106 -0
  42. package/components/Switch/Switch.astro +101 -0
  43. package/components/Switch/SwitchInput.astro +25 -0
  44. package/components/Table/Body.astro +13 -0
  45. package/components/Table/Cell.astro +13 -0
  46. package/components/Table/Column.astro +15 -0
  47. package/components/Table/ColumnGroup.astro +13 -0
  48. package/components/Table/Head.astro +13 -0
  49. package/components/Table/HeaderCell.astro +13 -0
  50. package/components/Table/Row.astro +13 -0
  51. package/components/Table/Table.astro +15 -0
  52. package/components/Table/index.ts +20 -0
  53. package/components/Tabs/Tabs.astro +28 -0
  54. package/components/Tabs/TabsItem.astro +47 -0
  55. package/components/Tabs/TabsPanel.astro +21 -0
  56. package/components/Tabs/TabsTab.astro +19 -0
  57. package/components/Tabs/index.ts +14 -0
  58. package/components/TextField/TextField.astro +128 -0
  59. package/components/Textarea/Textarea.astro +106 -0
  60. package/components/Toast/Toast.astro +42 -0
  61. package/components/ToggleButton/ToggleButton.astro +53 -0
  62. package/components/ToggleGroup/ToggleGroup.astro +49 -0
  63. package/components/Tooltip/Tooltip.astro +30 -0
  64. package/{src/core → core}/normalize.css +194 -196
  65. package/core/palette.css +59 -0
  66. package/{src/core → core}/utils.css +71 -60
  67. package/css/components/accordion.css +174 -0
  68. package/css/components/anchor.css +27 -0
  69. package/{src/themes/theme-two → css}/components/avatar.css +65 -68
  70. package/css/components/badge.css +107 -0
  71. package/css/components/button-group.css +179 -0
  72. package/css/components/button.css +215 -0
  73. package/css/components/callout.css +109 -0
  74. package/css/components/card.css +117 -0
  75. package/css/components/checkbox.css +205 -0
  76. package/{src/themes/theme-one → css}/components/chip.css +87 -135
  77. package/{src/themes/theme-two/components/definition-list.css → css/components/description-list.css} +77 -68
  78. package/{src/themes/theme-two → css}/components/dialog.css +68 -59
  79. package/css/components/divider.css +20 -0
  80. package/css/components/drawer.css +171 -0
  81. package/css/components/form.css +146 -0
  82. package/css/components/icon-button.css +139 -0
  83. package/{src/themes/theme-two → css}/components/link.css +21 -21
  84. package/{src/themes/theme-two → css}/components/list.css +345 -318
  85. package/{src/themes/theme-one → css}/components/progress.css +97 -83
  86. package/css/components/radio.css +172 -0
  87. package/css/components/range.css +337 -0
  88. package/{src/themes/theme-two → css}/components/select.css +169 -162
  89. package/{src/themes/theme-two → css}/components/spinner.css +37 -38
  90. package/{src/themes/theme-two → css}/components/switch.css +268 -225
  91. package/css/components/table.css +179 -0
  92. package/css/components/tabs.css +77 -0
  93. package/css/components/text-field.css +450 -0
  94. package/css/components/text-input.css +53 -0
  95. package/{src/themes/theme-two → css}/components/textarea.css +24 -25
  96. package/css/components/toast.css +161 -0
  97. package/css/components/toggle-button.css +87 -0
  98. package/css/components/toggle-group.css +56 -0
  99. package/css/components/tooltip.css +67 -0
  100. package/css/components/typography.css +585 -0
  101. package/{src/themes/theme-two → css}/components.css +41 -37
  102. package/{src/themes/theme-two → css}/imports.css +16 -16
  103. package/css/js/checkbox.js +21 -0
  104. package/css/js/toast.js +94 -0
  105. package/css/theme.css +132 -0
  106. package/dist/op.css +1001 -32
  107. package/dist/op.css.map +1 -0
  108. package/dist/opui.components.css +5135 -0
  109. package/dist/opui.components.css.map +1 -0
  110. package/dist/opui.css +6604 -0
  111. package/dist/opui.css.map +1 -0
  112. package/env.d.ts +14 -0
  113. package/open-props.css +9 -0
  114. package/package.json +64 -55
  115. package/dist/theme-one/components.css +0 -3869
  116. package/dist/theme-one/theme-one.css +0 -4424
  117. package/dist/theme-two/components.css +0 -3591
  118. package/dist/theme-two/theme-two.css +0 -4141
  119. package/src/open-props.css +0 -10
  120. package/src/themes/theme-one/components/accordion.css +0 -172
  121. package/src/themes/theme-one/components/alert.css +0 -85
  122. package/src/themes/theme-one/components/avatar.css +0 -68
  123. package/src/themes/theme-one/components/badge.css +0 -101
  124. package/src/themes/theme-one/components/button-group.css +0 -69
  125. package/src/themes/theme-one/components/button.css +0 -281
  126. package/src/themes/theme-one/components/card.css +0 -82
  127. package/src/themes/theme-one/components/checkbox-radio.css +0 -123
  128. package/src/themes/theme-one/components/definition-list.css +0 -68
  129. package/src/themes/theme-one/components/dialog.css +0 -59
  130. package/src/themes/theme-one/components/divider.css +0 -7
  131. package/src/themes/theme-one/components/field-group.css +0 -83
  132. package/src/themes/theme-one/components/field.css +0 -494
  133. package/src/themes/theme-one/components/icon-button.css +0 -40
  134. package/src/themes/theme-one/components/link.css +0 -21
  135. package/src/themes/theme-one/components/list.css +0 -318
  136. package/src/themes/theme-one/components/range.css +0 -121
  137. package/src/themes/theme-one/components/rich-text.css +0 -210
  138. package/src/themes/theme-one/components/select.css +0 -163
  139. package/src/themes/theme-one/components/snackbar.css +0 -148
  140. package/src/themes/theme-one/components/spinner.css +0 -38
  141. package/src/themes/theme-one/components/switch.css +0 -225
  142. package/src/themes/theme-one/components/tab-buttons.css +0 -120
  143. package/src/themes/theme-one/components/table.css +0 -92
  144. package/src/themes/theme-one/components/text-field.css +0 -57
  145. package/src/themes/theme-one/components/textarea.css +0 -25
  146. package/src/themes/theme-one/components/toggle-button-group.css +0 -135
  147. package/src/themes/theme-one/components/tooltip.css +0 -94
  148. package/src/themes/theme-one/components/typography.css +0 -209
  149. package/src/themes/theme-one/components.css +0 -37
  150. package/src/themes/theme-one/imports.css +0 -16
  151. package/src/themes/theme-one/theme.css +0 -163
  152. package/src/themes/theme-two/components/accordion.css +0 -172
  153. package/src/themes/theme-two/components/alert.css +0 -85
  154. package/src/themes/theme-two/components/badge.css +0 -101
  155. package/src/themes/theme-two/components/button-group.css +0 -50
  156. package/src/themes/theme-two/components/button.css +0 -229
  157. package/src/themes/theme-two/components/card.css +0 -82
  158. package/src/themes/theme-two/components/checkbox-radio.css +0 -123
  159. package/src/themes/theme-two/components/chip.css +0 -135
  160. package/src/themes/theme-two/components/divider.css +0 -7
  161. package/src/themes/theme-two/components/field-group.css +0 -83
  162. package/src/themes/theme-two/components/field.css +0 -281
  163. package/src/themes/theme-two/components/icon-button.css +0 -40
  164. package/src/themes/theme-two/components/progress.css +0 -83
  165. package/src/themes/theme-two/components/range.css +0 -121
  166. package/src/themes/theme-two/components/rich-text.css +0 -210
  167. package/src/themes/theme-two/components/snackbar.css +0 -148
  168. package/src/themes/theme-two/components/tab-buttons.css +0 -120
  169. package/src/themes/theme-two/components/table.css +0 -99
  170. package/src/themes/theme-two/components/text-field.css +0 -57
  171. package/src/themes/theme-two/components/toggle-button-group.css +0 -135
  172. package/src/themes/theme-two/components/tooltip.css +0 -94
  173. package/src/themes/theme-two/components/typography.css +0 -209
  174. package/src/themes/theme-two/theme.css +0 -158
@@ -1,3591 +0,0 @@
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
- }