opui-css 2.4.0 → 3.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 (80) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +23 -7
  3. package/dist/op.css +1 -14
  4. package/dist/{op+ui.css → theme-one.css} +4378 -4155
  5. package/dist/{ui.css → theme-two.css} +4097 -4100
  6. package/package.json +10 -8
  7. package/src/core/normalize.css +196 -196
  8. package/src/core/utils.css +60 -60
  9. package/src/open-props.css +1 -1
  10. package/src/{components → themes/theme-one/components}/accordion.css +172 -172
  11. package/src/{components → themes/theme-one/components}/alert.css +85 -85
  12. package/src/{components → themes/theme-one/components}/avatar.css +68 -68
  13. package/src/{components → themes/theme-one/components}/badge.css +101 -101
  14. package/src/{components → themes/theme-one/components}/button-group.css +69 -69
  15. package/src/{components → themes/theme-one/components}/button.css +267 -267
  16. package/src/{components → themes/theme-one/components}/card.css +82 -82
  17. package/src/{components → themes/theme-one/components}/checkbox-radio.css +123 -123
  18. package/src/{components → themes/theme-one/components}/chip.css +135 -135
  19. package/src/{components → themes/theme-one/components}/definition-list.css +65 -65
  20. package/src/{components → themes/theme-one/components}/dialog.css +59 -59
  21. package/src/{components → themes/theme-one/components}/divider.css +7 -7
  22. package/src/{components → themes/theme-one/components}/field-group.css +83 -83
  23. package/src/{components → themes/theme-one/components}/field.css +494 -494
  24. package/src/{components → themes/theme-one/components}/icon-button.css +40 -40
  25. package/src/{components → themes/theme-one/components}/link.css +21 -21
  26. package/src/{components → themes/theme-one/components}/list.css +317 -317
  27. package/src/{components → themes/theme-one/components}/progress.css +83 -83
  28. package/src/{components → themes/theme-one/components}/range.css +121 -121
  29. package/src/{components → themes/theme-one/components}/rich-text.css +210 -210
  30. package/src/{components → themes/theme-one/components}/select.css +163 -163
  31. package/src/{components → themes/theme-one/components}/snackbar.css +148 -148
  32. package/src/{components → themes/theme-one/components}/spinner.css +38 -38
  33. package/src/{components → themes/theme-one/components}/switch.css +189 -189
  34. package/src/{components → themes/theme-one/components}/tab-buttons.css +120 -120
  35. package/src/themes/theme-one/components/table.css +100 -0
  36. package/src/{components → themes/theme-one/components}/text-field.css +57 -57
  37. package/src/{components → themes/theme-one/components}/textarea.css +25 -25
  38. package/src/{components → themes/theme-one/components}/toggle-button-group.css +135 -139
  39. package/src/{components → themes/theme-one/components}/tooltip.css +94 -94
  40. package/src/{components → themes/theme-one/components}/typography.css +209 -209
  41. package/src/themes/theme-one/components.css +37 -0
  42. package/src/themes/theme-one/imports.css +16 -0
  43. package/src/{theme.css → themes/theme-one/theme.css} +163 -163
  44. package/src/themes/theme-two/components/accordion.css +172 -0
  45. package/src/themes/theme-two/components/alert.css +85 -0
  46. package/src/themes/theme-two/components/avatar.css +68 -0
  47. package/src/themes/theme-two/components/badge.css +101 -0
  48. package/src/themes/theme-two/components/button-group.css +50 -0
  49. package/src/themes/theme-two/components/button.css +217 -0
  50. package/src/themes/theme-two/components/card.css +82 -0
  51. package/src/themes/theme-two/components/checkbox-radio.css +123 -0
  52. package/src/themes/theme-two/components/chip.css +135 -0
  53. package/src/themes/theme-two/components/definition-list.css +65 -0
  54. package/src/themes/theme-two/components/dialog.css +59 -0
  55. package/src/themes/theme-two/components/divider.css +7 -0
  56. package/src/themes/theme-two/components/field-group.css +83 -0
  57. package/src/themes/theme-two/components/field.css +281 -0
  58. package/src/themes/theme-two/components/icon-button.css +40 -0
  59. package/src/themes/theme-two/components/link.css +21 -0
  60. package/src/themes/theme-two/components/list.css +317 -0
  61. package/src/themes/theme-two/components/progress.css +83 -0
  62. package/src/themes/theme-two/components/range.css +121 -0
  63. package/src/themes/theme-two/components/rich-text.css +210 -0
  64. package/src/themes/theme-two/components/select.css +162 -0
  65. package/src/themes/theme-two/components/snackbar.css +148 -0
  66. package/src/themes/theme-two/components/spinner.css +38 -0
  67. package/src/themes/theme-two/components/switch.css +189 -0
  68. package/src/themes/theme-two/components/tab-buttons.css +120 -0
  69. package/src/{components → themes/theme-two/components}/table.css +107 -107
  70. package/src/themes/theme-two/components/text-field.css +57 -0
  71. package/src/themes/theme-two/components/textarea.css +25 -0
  72. package/src/themes/theme-two/components/toggle-button-group.css +135 -0
  73. package/src/themes/theme-two/components/tooltip.css +94 -0
  74. package/src/themes/theme-two/components/typography.css +209 -0
  75. package/src/themes/theme-two/components.css +37 -0
  76. package/src/themes/theme-two/imports.css +16 -0
  77. package/src/themes/theme-two/theme.css +158 -0
  78. package/src/core/components.css +0 -37
  79. package/src/main.css +0 -13
  80. package/src/opui.css +0 -10
@@ -1,494 +1,494 @@
1
- @layer components.extended {
2
- /*
3
- - Common styling for input, textarea and select
4
- - Form related styles such as: label, supporting text, error handling
5
- */
6
- :where(.field) {
7
- --_accent-color: var(--primary);
8
- --_bg-color: var(--surface-default);
9
- --_border-color: var(--field-border-color);
10
- --_field-padding-block: 0.75rem;
11
- --_field-padding-inline: var(--size-2);
12
- --_filled-border-color: var(--text-color-1);
13
- --_height: var(--field-size);
14
- --_label-color: var(--text-color-2);
15
- --_supporting-text-color: var(--text-color-2);
16
-
17
- contain: layout;
18
- display: inline-grid;
19
- position: relative;
20
-
21
- /* Input/Select base */
22
- & input,
23
- & textarea,
24
- & select {
25
- background-color: var(--_bg-color);
26
- block-size: var(--_height);
27
- border-radius: var(--field-border-radius);
28
- border: var(--field-border-width) solid var(--_border-color);
29
- color: var(--text-color-1);
30
- font-family: var(--font-sans);
31
- font-size: var(--font-size-1);
32
- grid-column: 1/-1;
33
- grid-row: 1;
34
- inline-size: 100%;
35
- line-height: var(--font-lineheight-1);
36
- min-inline-size: 0;
37
- padding: var(--_field-padding-block) var(--_field-padding-inline);
38
-
39
- @media (prefers-reduced-motion: no-preference) {
40
- transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
41
- padding-block 0.2s var(--ease-3);
42
- }
43
- }
44
-
45
- /* Required/Invalid */
46
- &:has(
47
- :not(:placeholder-shown):invalid,
48
- :where(
49
- :placeholder-shown,
50
- option[value=""]:not(:checked),
51
- option:checked:not([value=""])
52
- ):required
53
- ) {
54
- .label:after {
55
- color: var(--red);
56
- content: "*";
57
- margin: -0.25em auto auto 0.25em;
58
- }
59
- }
60
-
61
- /* File */
62
- &:has(input[type="file"]) {
63
- cursor: pointer;
64
-
65
- input {
66
- align-self: flex-start;
67
- block-size: var(--_height);
68
- box-shadow: none;
69
- color: var(--text-color-1);
70
- cursor: inherit;
71
- max-inline-size: 100%;
72
- padding: 0;
73
- transition: font-size 0.2s var(--ease-3);
74
-
75
- &::-webkit-file-upload-button,
76
- &::file-selector-button {
77
- background-color: var(--surface-tonal);
78
- border: none;
79
- block-size: calc(100% - var(--size-2) * 2);
80
- border-radius: var(--field-border-radius);
81
- cursor: pointer;
82
- margin-inline-end: 1ex;
83
- margin-block-start: var(--size-2);
84
- margin-inline-start: var(--size-2);
85
- }
86
- }
87
-
88
- /* Variants */
89
- &.filled {
90
- input {
91
- &::-webkit-file-upload-button,
92
- &::file-selector-button {
93
- background-color: var(--surface-default);
94
- block-size: calc(100% - var(--size-2) * 2);
95
- border-radius: var(--field-border-radius);
96
- cursor: pointer;
97
- margin-block-start: var(--size-2);
98
- }
99
- }
100
- }
101
-
102
- /* Sizes */
103
- &.small {
104
- input {
105
- font-size: var(--font-size-sm);
106
- &::-webkit-file-upload-button,
107
- &::file-selector-button {
108
- block-size: calc(100% - var(--size-2));
109
- margin-block-start: var(--size-1);
110
- }
111
- }
112
- }
113
- }
114
-
115
- /* Autosuggest */
116
- &:has(input[list]) {
117
- .label {
118
- /* Make sure chevron is visible */
119
- inline-size: calc(100% - var(--size-6));
120
- }
121
- }
122
-
123
- /* Select */
124
- &:has(select) {
125
- .label {
126
- /* Make sure chevron is visible */
127
- inline-size: calc(100% - var(--size-6));
128
- }
129
- }
130
-
131
- /* Experimental Select */
132
- &:has(select button) {
133
- select {
134
- padding: 0;
135
-
136
- button {
137
- outline: 0;
138
- padding: var(--_field-padding-block) var(--size-8)
139
- var(--_field-padding-block) var(--_field-padding-inline);
140
- }
141
- }
142
- }
143
-
144
- /* Non-experimental Select */
145
- &:has(select):not(:has(button)) {
146
- select {
147
- padding: var(--_field-padding-block) var(--size-8)
148
- var(--_field-padding-block) var(--_field-padding-inline);
149
- }
150
- }
151
-
152
- /* Input - color */
153
- &:has(input[type="color"]) {
154
- input {
155
- appearance: none;
156
- background: none;
157
- block-size: var(--_height);
158
- overflow: hidden;
159
- padding: 0;
160
-
161
- &::-webkit-color-swatch {
162
- border: none;
163
- }
164
-
165
- &::-webkit-color-swatch-wrapper {
166
- padding: 0;
167
- }
168
- }
169
-
170
- .label {
171
- border: 1px solid var(--field-border-color);
172
- inline-size: fit-content;
173
- margin-inline-start: var(--size-2);
174
- }
175
- }
176
-
177
- /* Textarea */
178
- &:has(textarea) {
179
- .label {
180
- align-self: start;
181
- margin-block-start: var(--_field-padding-block);
182
- }
183
- }
184
-
185
- /*
186
- * Variant: Outlined
187
- */
188
- &:not(.filled) {
189
- /* Element states */
190
- &:hover {
191
- &:not(.error) {
192
- :where(input, textarea, select) {
193
- --_border-color: var(--text-color-1);
194
- }
195
- }
196
- }
197
- }
198
-
199
- &:not(.filled):focus-within {
200
- & input,
201
- & textarea,
202
- & select {
203
- border-color: var(--_accent-color);
204
- outline-offset: -2px;
205
- outline: 2px solid var(--_accent-color);
206
- }
207
- }
208
-
209
- /* Label */
210
- .label {
211
- align-self: center;
212
- background-color: var(--_bg-color);
213
- border-radius: var(--field-border-radius);
214
- color: var(--_label-color);
215
- border-radius: var(--radius-1);
216
- display: inline-flex;
217
- font-size: var(--font-size-md);
218
- grid-column: 1/-1;
219
- grid-row: 1;
220
- inline-size: calc(100% - (var(--field-border-width) * 2));
221
- margin-inline-start: var(--field-border-width);
222
- padding-inline: var(--_field-padding-inline);
223
- pointer-events: none;
224
- z-index: 1;
225
-
226
- @media (prefers-reduced-motion: no-preference) {
227
- transition: border-color 0.2s var(--ease-3),
228
- font-size 0.2s var(--ease-3), inline-size 0.05s var(--ease-3),
229
- margin 0.2s var(--ease-3), padding-inline 0.2s var(--ease-3);
230
- }
231
- }
232
-
233
- /*
234
- * Label transitions
235
- * Triggered by:
236
- * - focus
237
- * - filled form fields (except color inputs)
238
- * - non-empty select options
239
- */
240
- &:focus-within,
241
- &:has(:where(input:not([type="color"]), textarea):not(:placeholder-shown)),
242
- &:has(option[value=""]:not(:checked)),
243
- &:has(option:checked:not([value=""])) {
244
- .label {
245
- border-color: transparent;
246
- color: var(--_accent-color);
247
- font-size: 0.75rem;
248
- inline-size: max-content;
249
- letter-spacing: 0.15px;
250
- line-height: 1.15;
251
- margin-block-start: -2.7rem;
252
- margin-inline-start: var(--_field-padding-inline);
253
- padding-inline: 0.125rem;
254
- }
255
-
256
- /* Neutral label color reset */
257
- &:not(:focus-within):not(.error) {
258
- .label {
259
- color: var(--text-color-2);
260
- }
261
- }
262
-
263
- &:has(textarea) {
264
- .label {
265
- margin-block-start: -0.35rem;
266
- }
267
-
268
- &.small {
269
- .label {
270
- align-self: start;
271
- margin-block-start: var(--_field-padding-block);
272
- }
273
- }
274
- }
275
- }
276
-
277
- /* Supporting text */
278
- .supporting-text {
279
- color: var(--_supporting-text-color);
280
- font-size: var(--font-size-xs);
281
- grid-row: 3;
282
- line-height: 1.5;
283
- margin-inline-start: var(--field-border-width);
284
- padding-inline: var(--_field-padding-inline);
285
- z-index: 1;
286
- }
287
-
288
- /* Auto-fit */
289
- &.auto-fit {
290
- inline-size: auto;
291
- :where(& input, & textarea) {
292
- field-sizing: content;
293
- }
294
- }
295
-
296
- /* Validation */
297
- &.error {
298
- --_accent-color: var(--color-9);
299
- --_border-color: var(--color-9);
300
- --_filled-border-color: var(--color-9);
301
- --_label-color: var(--color-9);
302
- --_supporting-text-color: var(--color-9);
303
- }
304
-
305
- /*
306
- * Variant: Filled
307
- */
308
- &.filled {
309
- --_bg-color: var(--surface-tonal);
310
- *:focus-visible {
311
- outline: 0;
312
- }
313
-
314
- /* Base style */
315
- & input,
316
- & textarea,
317
- & select {
318
- border-block-end-color: var(--_filled-border-color);
319
- border-block-start-color: transparent;
320
- border-inline-color: transparent;
321
- border-radius: 0;
322
- }
323
-
324
- & input[type="color"] {
325
- border-inline: none;
326
- }
327
-
328
- /* Bottom line */
329
- &::before {
330
- background-color: var(--_filled-border-color);
331
- block-size: calc(var(--field-border-width) + 1px);
332
- content: "";
333
- inline-size: 100%;
334
- margin-block-end: calc(-1 * (var(--field-border-width) * 2));
335
- transform: scaleX(0);
336
- translate: 0 calc(-1 * (var(--field-border-width) * 2));
337
- z-index: 1;
338
-
339
- @media (prefers-reduced-motion: no-preference) {
340
- transition: transform 0.3s var(--ease-3), translate 0.2s var(--ease-3);
341
- }
342
- }
343
-
344
- /* Label */
345
- .label {
346
- background-color: var(--_bg-color);
347
- }
348
-
349
- &:not(:has([disabled], :has(input[type="color"]))) {
350
- /* Hover */
351
- &:hover {
352
- --_bg-color: light-dark(
353
- oklch(from var(--surface-tonal) calc(l * 0.93) c h),
354
- oklch(from var(--surface-tonal) calc(l * 1.1) c h)
355
- );
356
- }
357
- }
358
-
359
- /*
360
- * Label transitions
361
- * Triggered by:
362
- * - focus
363
- * - filled form fields (except color inputs)
364
- * - non-empty select options
365
- */
366
- &:has(.label) {
367
- &:focus-within,
368
- &:has(
369
- :where(input:not(:where([type="color"])), textarea):not(
370
- :placeholder-shown
371
- )
372
- ),
373
- &:has(option[value=""]:not(:checked)),
374
- &:has(option:checked:not([value=""])) {
375
- :where(input, textarea) {
376
- padding-block: calc(var(--_field-padding-block) * 1.7)
377
- calc(var(--_field-padding-block) * 0.3);
378
- }
379
-
380
- select > button,
381
- select:not(:has(button)) {
382
- padding-block: calc(var(--_field-padding-block) * 1.7)
383
- calc(var(--_field-padding-block) * 0.3);
384
- }
385
-
386
- .label {
387
- margin-block-start: calc(-1 * var(--size-5));
388
- margin-inline-start: calc(var(--_field-padding-inline) / 2);
389
- padding-inline: calc(var(--_field-padding-inline) / 2);
390
- }
391
-
392
- &:has(textarea) {
393
- .label {
394
- margin-block-start: var(--size-1);
395
- }
396
- }
397
- }
398
- }
399
-
400
- /* Element states */
401
- &:hover {
402
- &::before {
403
- transform: scaleX(1);
404
- }
405
- }
406
- &:focus-within {
407
- & input,
408
- & textarea,
409
- & select {
410
- border-block-end-color: var(--_accent-color);
411
- }
412
-
413
- &::before {
414
- background-color: var(--_accent-color);
415
- transform: scaleX(1) translateX(0px);
416
- }
417
- }
418
- }
419
-
420
- /* Disabled */
421
- &:where(:has([disabled])) {
422
- &::before {
423
- display: none;
424
- }
425
- :where(input, textarea, select) {
426
- cursor: not-allowed;
427
- opacity: 0.7;
428
-
429
- * {
430
- pointer-events: none;
431
- }
432
- }
433
- }
434
-
435
- /* Read-only */
436
- &:where(:has([readonly])) {
437
- &::before {
438
- display: none;
439
- }
440
- :where(input, textarea, select) {
441
- cursor: not-allowed;
442
-
443
- * {
444
- pointer-events: none;
445
- }
446
- }
447
- }
448
-
449
- /* Sizes */
450
- &.small {
451
- --_field-padding-block: var(--size-2);
452
- --_height: var(--field-size-small);
453
-
454
- &:has(input[type="color"]) {
455
- .label {
456
- line-height: 1.5;
457
- }
458
- }
459
-
460
- &:has(textarea) {
461
- .label {
462
- align-self: center;
463
- margin-block-start: unset;
464
- }
465
- }
466
-
467
- /*
468
- * Label transitions
469
- * Triggered by:
470
- * - focus
471
- * - filled form fields (except color inputs)
472
- * - non-empty select options
473
- */
474
- &:focus-within,
475
- &:has(
476
- :where(input:not([type="color"]), textarea):not(:placeholder-shown)
477
- ),
478
- &:has(option[value=""]:not(:checked)),
479
- &:has(option:checked:not([value=""])) {
480
- .label {
481
- margin-block-start: -2.2rem;
482
- margin-inline-start: var(--size-1);
483
- padding-inline: var(--size-1);
484
- }
485
-
486
- &:not(.filled):has(textarea) {
487
- .label {
488
- margin-block-start: -0.35rem;
489
- }
490
- }
491
- }
492
- }
493
- }
494
- }
1
+ @layer components.extended {
2
+ /*
3
+ - Common styling for input, textarea and select
4
+ - Form related styles such as: label, supporting text, error handling
5
+ */
6
+ :where(.field) {
7
+ --_accent-color: var(--primary);
8
+ --_bg-color: var(--surface-default);
9
+ --_border-color: var(--field-border-color);
10
+ --_field-padding-block: 0.75rem;
11
+ --_field-padding-inline: var(--size-2);
12
+ --_filled-border-color: var(--text-color-1);
13
+ --_height: var(--field-size);
14
+ --_label-color: var(--text-color-2);
15
+ --_supporting-text-color: var(--text-color-2);
16
+
17
+ contain: layout;
18
+ display: inline-grid;
19
+ position: relative;
20
+
21
+ /* Input/Select base */
22
+ & input,
23
+ & textarea,
24
+ & select {
25
+ background-color: var(--_bg-color);
26
+ block-size: var(--_height);
27
+ border-radius: var(--field-border-radius);
28
+ border: var(--field-border-width) solid var(--_border-color);
29
+ color: var(--text-color-1);
30
+ font-family: var(--font-sans);
31
+ font-size: var(--font-size-1);
32
+ grid-column: 1/-1;
33
+ grid-row: 1;
34
+ inline-size: 100%;
35
+ line-height: var(--font-lineheight-1);
36
+ min-inline-size: 0;
37
+ padding: var(--_field-padding-block) var(--_field-padding-inline);
38
+
39
+ @media (prefers-reduced-motion: no-preference) {
40
+ transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
41
+ padding-block 0.2s var(--ease-3);
42
+ }
43
+ }
44
+
45
+ /* Required/Invalid */
46
+ &:has(
47
+ :not(:placeholder-shown):invalid,
48
+ :where(
49
+ :placeholder-shown,
50
+ option[value=""]:not(:checked),
51
+ option:checked:not([value=""])
52
+ ):required
53
+ ) {
54
+ .label:after {
55
+ color: var(--red);
56
+ content: "*";
57
+ margin: -0.25em auto auto 0.25em;
58
+ }
59
+ }
60
+
61
+ /* File */
62
+ &:has(input[type="file"]) {
63
+ cursor: pointer;
64
+
65
+ input {
66
+ align-self: flex-start;
67
+ block-size: var(--_height);
68
+ box-shadow: none;
69
+ color: var(--text-color-1);
70
+ cursor: inherit;
71
+ max-inline-size: 100%;
72
+ padding: 0;
73
+ transition: font-size 0.2s var(--ease-3);
74
+
75
+ &::-webkit-file-upload-button,
76
+ &::file-selector-button {
77
+ background-color: var(--surface-tonal);
78
+ border: none;
79
+ block-size: calc(100% - var(--size-2) * 2);
80
+ border-radius: var(--field-border-radius);
81
+ cursor: pointer;
82
+ margin-inline-end: 1ex;
83
+ margin-block-start: var(--size-2);
84
+ margin-inline-start: var(--size-2);
85
+ }
86
+ }
87
+
88
+ /* Variants */
89
+ &.filled {
90
+ input {
91
+ &::-webkit-file-upload-button,
92
+ &::file-selector-button {
93
+ background-color: var(--surface-default);
94
+ block-size: calc(100% - var(--size-2) * 2);
95
+ border-radius: var(--field-border-radius);
96
+ cursor: pointer;
97
+ margin-block-start: var(--size-2);
98
+ }
99
+ }
100
+ }
101
+
102
+ /* Sizes */
103
+ &.small {
104
+ input {
105
+ font-size: var(--font-size-sm);
106
+ &::-webkit-file-upload-button,
107
+ &::file-selector-button {
108
+ block-size: calc(100% - var(--size-2));
109
+ margin-block-start: var(--size-1);
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ /* Autosuggest */
116
+ &:has(input[list]) {
117
+ .label {
118
+ /* Make sure chevron is visible */
119
+ inline-size: calc(100% - var(--size-6));
120
+ }
121
+ }
122
+
123
+ /* Select */
124
+ &:has(select) {
125
+ .label {
126
+ /* Make sure chevron is visible */
127
+ inline-size: calc(100% - var(--size-6));
128
+ }
129
+ }
130
+
131
+ /* Experimental Select */
132
+ &:has(select button) {
133
+ select {
134
+ padding: 0;
135
+
136
+ button {
137
+ outline: 0;
138
+ padding: var(--_field-padding-block) var(--size-8)
139
+ var(--_field-padding-block) var(--_field-padding-inline);
140
+ }
141
+ }
142
+ }
143
+
144
+ /* Non-experimental Select */
145
+ &:has(select):not(:has(button)) {
146
+ select {
147
+ padding: var(--_field-padding-block) var(--size-8)
148
+ var(--_field-padding-block) var(--_field-padding-inline);
149
+ }
150
+ }
151
+
152
+ /* Input - color */
153
+ &:has(input[type="color"]) {
154
+ input {
155
+ appearance: none;
156
+ background: none;
157
+ block-size: var(--_height);
158
+ overflow: hidden;
159
+ padding: 0;
160
+
161
+ &::-webkit-color-swatch {
162
+ border: none;
163
+ }
164
+
165
+ &::-webkit-color-swatch-wrapper {
166
+ padding: 0;
167
+ }
168
+ }
169
+
170
+ .label {
171
+ border: 1px solid var(--field-border-color);
172
+ inline-size: fit-content;
173
+ margin-inline-start: var(--size-2);
174
+ }
175
+ }
176
+
177
+ /* Textarea */
178
+ &:has(textarea) {
179
+ .label {
180
+ align-self: start;
181
+ margin-block-start: var(--_field-padding-block);
182
+ }
183
+ }
184
+
185
+ /*
186
+ * Variant: Outlined
187
+ */
188
+ &:not(.filled) {
189
+ /* Element states */
190
+ &:hover {
191
+ &:not(.error) {
192
+ :where(input, textarea, select) {
193
+ --_border-color: var(--text-color-1);
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ &:not(.filled):focus-within {
200
+ & input,
201
+ & textarea,
202
+ & select {
203
+ border-color: var(--_accent-color);
204
+ outline-offset: -2px;
205
+ outline: 2px solid var(--_accent-color);
206
+ }
207
+ }
208
+
209
+ /* Label */
210
+ .label {
211
+ align-self: center;
212
+ background-color: var(--_bg-color);
213
+ border-radius: var(--field-border-radius);
214
+ color: var(--_label-color);
215
+ border-radius: var(--radius-1);
216
+ display: inline-flex;
217
+ font-size: var(--font-size-md);
218
+ grid-column: 1/-1;
219
+ grid-row: 1;
220
+ inline-size: calc(100% - (var(--field-border-width) * 2));
221
+ margin-inline-start: var(--field-border-width);
222
+ padding-inline: var(--_field-padding-inline);
223
+ pointer-events: none;
224
+ z-index: 1;
225
+
226
+ @media (prefers-reduced-motion: no-preference) {
227
+ transition: border-color 0.2s var(--ease-3),
228
+ font-size 0.2s var(--ease-3), inline-size 0.05s var(--ease-3),
229
+ margin 0.2s var(--ease-3), padding-inline 0.2s var(--ease-3);
230
+ }
231
+ }
232
+
233
+ /*
234
+ * Label transitions
235
+ * Triggered by:
236
+ * - focus
237
+ * - filled form fields (except color inputs)
238
+ * - non-empty select options
239
+ */
240
+ &:focus-within,
241
+ &:has(:where(input:not([type="color"]), textarea):not(:placeholder-shown)),
242
+ &:has(option[value=""]:not(:checked)),
243
+ &:has(option:checked:not([value=""])) {
244
+ .label {
245
+ border-color: transparent;
246
+ color: var(--_accent-color);
247
+ font-size: 0.75rem;
248
+ inline-size: max-content;
249
+ letter-spacing: 0.15px;
250
+ line-height: 1.15;
251
+ margin-block-start: -2.7rem;
252
+ margin-inline-start: var(--_field-padding-inline);
253
+ padding-inline: 0.125rem;
254
+ }
255
+
256
+ /* Neutral label color reset */
257
+ &:not(:focus-within):not(.error) {
258
+ .label {
259
+ color: var(--text-color-2);
260
+ }
261
+ }
262
+
263
+ &:has(textarea) {
264
+ .label {
265
+ margin-block-start: -0.35rem;
266
+ }
267
+
268
+ &.small {
269
+ .label {
270
+ align-self: start;
271
+ margin-block-start: var(--_field-padding-block);
272
+ }
273
+ }
274
+ }
275
+ }
276
+
277
+ /* Supporting text */
278
+ .supporting-text {
279
+ color: var(--_supporting-text-color);
280
+ font-size: var(--font-size-xs);
281
+ grid-row: 3;
282
+ line-height: 1.5;
283
+ margin-inline-start: var(--field-border-width);
284
+ padding-inline: var(--_field-padding-inline);
285
+ z-index: 1;
286
+ }
287
+
288
+ /* Auto-fit */
289
+ &.auto-fit {
290
+ inline-size: auto;
291
+ :where(& input, & textarea) {
292
+ field-sizing: content;
293
+ }
294
+ }
295
+
296
+ /* Validation */
297
+ &.error {
298
+ --_accent-color: var(--color-9);
299
+ --_border-color: var(--color-9);
300
+ --_filled-border-color: var(--color-9);
301
+ --_label-color: var(--color-9);
302
+ --_supporting-text-color: var(--color-9);
303
+ }
304
+
305
+ /*
306
+ * Variant: Filled
307
+ */
308
+ &.filled {
309
+ --_bg-color: var(--surface-tonal);
310
+ *:focus-visible {
311
+ outline: 0;
312
+ }
313
+
314
+ /* Base style */
315
+ & input,
316
+ & textarea,
317
+ & select {
318
+ border-block-end-color: var(--_filled-border-color);
319
+ border-block-start-color: transparent;
320
+ border-inline-color: transparent;
321
+ border-radius: 0;
322
+ }
323
+
324
+ & input[type="color"] {
325
+ border-inline: none;
326
+ }
327
+
328
+ /* Bottom line */
329
+ &::before {
330
+ background-color: var(--_filled-border-color);
331
+ block-size: calc(var(--field-border-width) + 1px);
332
+ content: "";
333
+ inline-size: 100%;
334
+ margin-block-end: calc(-1 * (var(--field-border-width) * 2));
335
+ transform: scaleX(0);
336
+ translate: 0 calc(-1 * (var(--field-border-width) * 2));
337
+ z-index: 1;
338
+
339
+ @media (prefers-reduced-motion: no-preference) {
340
+ transition: transform 0.3s var(--ease-3), translate 0.2s var(--ease-3);
341
+ }
342
+ }
343
+
344
+ /* Label */
345
+ .label {
346
+ background-color: var(--_bg-color);
347
+ }
348
+
349
+ &:not(:has([disabled], :has(input[type="color"]))) {
350
+ /* Hover */
351
+ &:hover {
352
+ --_bg-color: light-dark(
353
+ oklch(from var(--surface-tonal) calc(l * 0.93) c h),
354
+ oklch(from var(--surface-tonal) calc(l * 1.1) c h)
355
+ );
356
+ }
357
+ }
358
+
359
+ /*
360
+ * Label transitions
361
+ * Triggered by:
362
+ * - focus
363
+ * - filled form fields (except color inputs)
364
+ * - non-empty select options
365
+ */
366
+ &:has(.label) {
367
+ &:focus-within,
368
+ &:has(
369
+ :where(input:not(:where([type="color"])), textarea):not(
370
+ :placeholder-shown
371
+ )
372
+ ),
373
+ &:has(option[value=""]:not(:checked)),
374
+ &:has(option:checked:not([value=""])) {
375
+ :where(input, textarea) {
376
+ padding-block: calc(var(--_field-padding-block) * 1.7)
377
+ calc(var(--_field-padding-block) * 0.3);
378
+ }
379
+
380
+ select > button,
381
+ select:not(:has(button)) {
382
+ padding-block: calc(var(--_field-padding-block) * 1.7)
383
+ calc(var(--_field-padding-block) * 0.3);
384
+ }
385
+
386
+ .label {
387
+ margin-block-start: calc(-1 * var(--size-5));
388
+ margin-inline-start: calc(var(--_field-padding-inline) / 2);
389
+ padding-inline: calc(var(--_field-padding-inline) / 2);
390
+ }
391
+
392
+ &:has(textarea) {
393
+ .label {
394
+ margin-block-start: var(--size-1);
395
+ }
396
+ }
397
+ }
398
+ }
399
+
400
+ /* Element states */
401
+ &:hover {
402
+ &::before {
403
+ transform: scaleX(1);
404
+ }
405
+ }
406
+ &:focus-within {
407
+ & input,
408
+ & textarea,
409
+ & select {
410
+ border-block-end-color: var(--_accent-color);
411
+ }
412
+
413
+ &::before {
414
+ background-color: var(--_accent-color);
415
+ transform: scaleX(1) translateX(0px);
416
+ }
417
+ }
418
+ }
419
+
420
+ /* Disabled */
421
+ &:where(:has([disabled])) {
422
+ &::before {
423
+ display: none;
424
+ }
425
+ :where(input, textarea, select) {
426
+ cursor: not-allowed;
427
+ opacity: 0.7;
428
+
429
+ * {
430
+ pointer-events: none;
431
+ }
432
+ }
433
+ }
434
+
435
+ /* Read-only */
436
+ &:where(:has([readonly])) {
437
+ &::before {
438
+ display: none;
439
+ }
440
+ :where(input, textarea, select) {
441
+ cursor: not-allowed;
442
+
443
+ * {
444
+ pointer-events: none;
445
+ }
446
+ }
447
+ }
448
+
449
+ /* Sizes */
450
+ &.small {
451
+ --_field-padding-block: var(--size-2);
452
+ --_height: var(--field-size-small);
453
+
454
+ &:has(input[type="color"]) {
455
+ .label {
456
+ line-height: 1.5;
457
+ }
458
+ }
459
+
460
+ &:has(textarea) {
461
+ .label {
462
+ align-self: center;
463
+ margin-block-start: unset;
464
+ }
465
+ }
466
+
467
+ /*
468
+ * Label transitions
469
+ * Triggered by:
470
+ * - focus
471
+ * - filled form fields (except color inputs)
472
+ * - non-empty select options
473
+ */
474
+ &:focus-within,
475
+ &:has(
476
+ :where(input:not([type="color"]), textarea):not(:placeholder-shown)
477
+ ),
478
+ &:has(option[value=""]:not(:checked)),
479
+ &:has(option:checked:not([value=""])) {
480
+ .label {
481
+ margin-block-start: -2.2rem;
482
+ margin-inline-start: var(--size-1);
483
+ padding-inline: var(--size-1);
484
+ }
485
+
486
+ &:not(.filled):has(textarea) {
487
+ .label {
488
+ margin-block-start: -0.35rem;
489
+ }
490
+ }
491
+ }
492
+ }
493
+ }
494
+ }