contain-css-svelte 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/Card.svelte +25 -0
  2. package/dist/controls/Button.svelte +43 -18
  3. package/dist/controls/ButtonLink.svelte +31 -92
  4. package/dist/controls/Checkbox.svelte +34 -4
  5. package/dist/controls/CircleButton.svelte +36 -95
  6. package/dist/controls/Input.svelte +25 -0
  7. package/dist/controls/RadioButton.svelte +27 -2
  8. package/dist/controls/Select.svelte +25 -0
  9. package/dist/controls/Slider.svelte +25 -0
  10. package/dist/controls/TabItem.svelte +25 -0
  11. package/dist/controls/Toggle.svelte +27 -2
  12. package/dist/dropdowns/DropdownMenu.svelte +60 -6
  13. package/dist/layout/Accordion.svelte +28 -3
  14. package/dist/layout/Bar.svelte +25 -0
  15. package/dist/layout/ColumnContainer.svelte +25 -0
  16. package/dist/layout/Columns.svelte +25 -0
  17. package/dist/layout/Container.svelte +25 -0
  18. package/dist/layout/DataList.svelte +25 -0
  19. package/dist/layout/DataListItem.svelte +28 -3
  20. package/dist/layout/Fieldset.svelte +25 -0
  21. package/dist/layout/Form.svelte +25 -0
  22. package/dist/layout/FormItem.svelte +25 -0
  23. package/dist/layout/GridLayout.svelte +25 -0
  24. package/dist/layout/Hero.svelte +35 -0
  25. package/dist/layout/Inline.svelte +25 -0
  26. package/dist/layout/MenuList.svelte +36 -11
  27. package/dist/layout/Page.svelte +25 -0
  28. package/dist/layout/RowContainer.svelte +25 -0
  29. package/dist/layout/Sidebar.svelte +37 -7
  30. package/dist/layout/SidebarContainer.svelte +25 -0
  31. package/dist/layout/SplitPane.svelte +25 -0
  32. package/dist/layout/Stack.svelte +25 -0
  33. package/dist/layout/TabBar.svelte +25 -0
  34. package/dist/layout/Table.svelte +75 -10
  35. package/dist/layout/Tile.svelte +28 -3
  36. package/dist/misc/CodeInner.svelte +49 -22
  37. package/dist/misc/Progress.svelte +25 -0
  38. package/dist/misc/Tag.svelte +25 -0
  39. package/dist/overlays/Dialog.svelte +58 -0
  40. package/dist/overlays/Tooltip.svelte +57 -1
  41. package/dist/sass/_affordances.scss +10 -4
  42. package/dist/sass/_typography.scss +53 -0
  43. package/dist/typography/TextLayout.svelte +25 -0
  44. package/dist/vars/affordances.css +9 -4
  45. package/dist/vars/code.css +12 -0
  46. package/dist/vars/colors.css +24 -19
  47. package/dist/vars/defaults.css +45 -23
  48. package/dist/vars/themes/dark.css +3 -3
  49. package/dist/vars/themes/light.css +34 -31
  50. package/package.json +1 -1
@@ -41,6 +41,31 @@ const el = $derived(elementProps(restProps, "input", INPUT_VARS));
41
41
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
42
42
  has to happen where the real element is, in the global consumer rule; only
43
43
  the VALUES move to context vars here. */
44
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
45
+ that sits in the DOM wherever its trigger was placed.
46
+
47
+ The top layer changes how an element paints and where it is positioned, not
48
+ what it inherits. A popover declared inside a `white-space: nowrap` table
49
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
50
+ bold, uppercase and centred -- styles that belong to the trigger's context,
51
+ not to the overlay. typography-props() doesn't stop that: its chains end in
52
+ `unset`, which for an inherited property means "take the parent's value".
53
+
54
+ So this re-declares every inherited text property with a real default at
55
+ the end of the same variable chain. The vars still win (--tooltip-*, then
56
+ the category, then the global), and custom properties still inherit --
57
+ that is how theming reaches an overlay -- but when nothing is set, the
58
+ overlay gets its own defaults instead of its host's.
59
+
60
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
61
+ same rule: it has to beat their `unset` fallbacks by source order.
62
+
63
+ Deliberately left inheriting:
64
+ - direction, writing-mode: the document's script direction is the
65
+ overlay's too.
66
+ - visibility: a hidden subtree should not be able to show an overlay.
67
+ - font-family: every theme defines --font-family at :root, and there is no
68
+ neutral value to fall back to that would beat "the page's font". */
44
69
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
45
70
  one value (both sides equal) or two (start end), so there is no separate
46
71
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -68,6 +68,31 @@ function handleChange() {
68
68
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
69
69
  has to happen where the real element is, in the global consumer rule; only
70
70
  the VALUES move to context vars here. */
71
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
72
+ that sits in the DOM wherever its trigger was placed.
73
+
74
+ The top layer changes how an element paints and where it is positioned, not
75
+ what it inherits. A popover declared inside a `white-space: nowrap` table
76
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
77
+ bold, uppercase and centred -- styles that belong to the trigger's context,
78
+ not to the overlay. typography-props() doesn't stop that: its chains end in
79
+ `unset`, which for an inherited property means "take the parent's value".
80
+
81
+ So this re-declares every inherited text property with a real default at
82
+ the end of the same variable chain. The vars still win (--tooltip-*, then
83
+ the category, then the global), and custom properties still inherit --
84
+ that is how theming reaches an overlay -- but when nothing is set, the
85
+ overlay gets its own defaults instead of its host's.
86
+
87
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
88
+ same rule: it has to beat their `unset` fallbacks by source order.
89
+
90
+ Deliberately left inheriting:
91
+ - direction, writing-mode: the document's script direction is the
92
+ overlay's too.
93
+ - visibility: a hidden subtree should not be able to show an overlay.
94
+ - font-family: every theme defines --font-family at :root, and there is no
95
+ neutral value to fall back to that would beat "the page's font". */
71
96
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
72
97
  one value (both sides equal) or two (start end), so there is no separate
73
98
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -286,14 +311,14 @@ label.radio-item:hover::before {
286
311
  filter: var(--radio-button-hover-filter, var(--clickable-hover-filter, var(--hover-filter, brightness(1.05))));
287
312
  transform: var(--radio-button-hover-transform, var(--clickable-hover-transform, var(--hover-transform, none)));
288
313
  color: var(--_color);
289
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
314
+ background-color: color-mix(in oklab, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, var(--_color, white)) calc(100% - var(--hover-base-color-percentage, 90%)));
290
315
  box-shadow: var(--radio-button-hover-box-shadow, var(--clickable-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none))));
291
316
  }
292
317
 
293
318
  label.radio-item:active::before {
294
319
  filter: var(--radio-button-active-filter, var(--clickable-active-filter, var(--active-filter, brightness(0.9))));
295
320
  transform: var(--radio-button-active-transform, var(--clickable-active-transform, var(--active-transform, none)));
296
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
321
+ background-color: color-mix(in oklab, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
297
322
  box-shadow: var(--radio-button-active-box-shadow, var(--clickable-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none))));
298
323
  }
299
324
 
@@ -167,6 +167,31 @@ $effect(() => {
167
167
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
168
168
  has to happen where the real element is, in the global consumer rule; only
169
169
  the VALUES move to context vars here. */
170
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
171
+ that sits in the DOM wherever its trigger was placed.
172
+
173
+ The top layer changes how an element paints and where it is positioned, not
174
+ what it inherits. A popover declared inside a `white-space: nowrap` table
175
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
176
+ bold, uppercase and centred -- styles that belong to the trigger's context,
177
+ not to the overlay. typography-props() doesn't stop that: its chains end in
178
+ `unset`, which for an inherited property means "take the parent's value".
179
+
180
+ So this re-declares every inherited text property with a real default at
181
+ the end of the same variable chain. The vars still win (--tooltip-*, then
182
+ the category, then the global), and custom properties still inherit --
183
+ that is how theming reaches an overlay -- but when nothing is set, the
184
+ overlay gets its own defaults instead of its host's.
185
+
186
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
187
+ same rule: it has to beat their `unset` fallbacks by source order.
188
+
189
+ Deliberately left inheriting:
190
+ - direction, writing-mode: the document's script direction is the
191
+ overlay's too.
192
+ - visibility: a hidden subtree should not be able to show an overlay.
193
+ - font-family: every theme defines --font-family at :root, and there is no
194
+ neutral value to fall back to that would beat "the page's font". */
170
195
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
171
196
  one value (both sides equal) or two (start end), so there is no separate
172
197
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -43,6 +43,31 @@ const el = $derived(elementProps(restProps, "slider", ["bg", "fg", "padding", "w
43
43
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
44
44
  has to happen where the real element is, in the global consumer rule; only
45
45
  the VALUES move to context vars here. */
46
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
47
+ that sits in the DOM wherever its trigger was placed.
48
+
49
+ The top layer changes how an element paints and where it is positioned, not
50
+ what it inherits. A popover declared inside a `white-space: nowrap` table
51
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
52
+ bold, uppercase and centred -- styles that belong to the trigger's context,
53
+ not to the overlay. typography-props() doesn't stop that: its chains end in
54
+ `unset`, which for an inherited property means "take the parent's value".
55
+
56
+ So this re-declares every inherited text property with a real default at
57
+ the end of the same variable chain. The vars still win (--tooltip-*, then
58
+ the category, then the global), and custom properties still inherit --
59
+ that is how theming reaches an overlay -- but when nothing is set, the
60
+ overlay gets its own defaults instead of its host's.
61
+
62
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
63
+ same rule: it has to beat their `unset` fallbacks by source order.
64
+
65
+ Deliberately left inheriting:
66
+ - direction, writing-mode: the document's script direction is the
67
+ overlay's too.
68
+ - visibility: a hidden subtree should not be able to show an overlay.
69
+ - font-family: every theme defines --font-family at :root, and there is no
70
+ neutral value to fall back to that would beat "the page's font". */
46
71
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
47
72
  one value (both sides equal) or two (start end), so there is no separate
48
73
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -55,6 +55,31 @@ const el = $derived(elementProps(restProps, "tab", [
55
55
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
56
56
  has to happen where the real element is, in the global consumer rule; only
57
57
  the VALUES move to context vars here. */
58
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
59
+ that sits in the DOM wherever its trigger was placed.
60
+
61
+ The top layer changes how an element paints and where it is positioned, not
62
+ what it inherits. A popover declared inside a `white-space: nowrap` table
63
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
64
+ bold, uppercase and centred -- styles that belong to the trigger's context,
65
+ not to the overlay. typography-props() doesn't stop that: its chains end in
66
+ `unset`, which for an inherited property means "take the parent's value".
67
+
68
+ So this re-declares every inherited text property with a real default at
69
+ the end of the same variable chain. The vars still win (--tooltip-*, then
70
+ the category, then the global), and custom properties still inherit --
71
+ that is how theming reaches an overlay -- but when nothing is set, the
72
+ overlay gets its own defaults instead of its host's.
73
+
74
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
75
+ same rule: it has to beat their `unset` fallbacks by source order.
76
+
77
+ Deliberately left inheriting:
78
+ - direction, writing-mode: the document's script direction is the
79
+ overlay's too.
80
+ - visibility: a hidden subtree should not be able to show an overlay.
81
+ - font-family: every theme defines --font-family at :root, and there is no
82
+ neutral value to fall back to that would beat "the page's font". */
58
83
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
59
84
  one value (both sides equal) or two (start end), so there is no separate
60
85
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -72,6 +72,31 @@ const effectiveOnLabel = $derived(onLabel || children);
72
72
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
73
73
  has to happen where the real element is, in the global consumer rule; only
74
74
  the VALUES move to context vars here. */
75
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
76
+ that sits in the DOM wherever its trigger was placed.
77
+
78
+ The top layer changes how an element paints and where it is positioned, not
79
+ what it inherits. A popover declared inside a `white-space: nowrap` table
80
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
81
+ bold, uppercase and centred -- styles that belong to the trigger's context,
82
+ not to the overlay. typography-props() doesn't stop that: its chains end in
83
+ `unset`, which for an inherited property means "take the parent's value".
84
+
85
+ So this re-declares every inherited text property with a real default at
86
+ the end of the same variable chain. The vars still win (--tooltip-*, then
87
+ the category, then the global), and custom properties still inherit --
88
+ that is how theming reaches an overlay -- but when nothing is set, the
89
+ overlay gets its own defaults instead of its host's.
90
+
91
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
92
+ same rule: it has to beat their `unset` fallbacks by source order.
93
+
94
+ Deliberately left inheriting:
95
+ - direction, writing-mode: the document's script direction is the
96
+ overlay's too.
97
+ - visibility: a hidden subtree should not be able to show an overlay.
98
+ - font-family: every theme defines --font-family at :root, and there is no
99
+ neutral value to fall back to that would beat "the page's font". */
75
100
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
76
101
  one value (both sides equal) or two (start end), so there is no separate
77
102
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -261,14 +286,14 @@ input[type=checkbox] {
261
286
  filter: var(--toggle-hover-filter, var(--clickable-hover-filter, var(--hover-filter, brightness(1.05))));
262
287
  transform: var(--toggle-hover-transform, var(--clickable-hover-transform, var(--hover-transform, none)));
263
288
  color: var(--_color);
264
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
289
+ background-color: color-mix(in oklab, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, var(--_color, white)) calc(100% - var(--hover-base-color-percentage, 90%)));
265
290
  box-shadow: var(--toggle-hover-box-shadow, var(--clickable-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none))));
266
291
  }
267
292
 
268
293
  .toggle:active .toggle-track {
269
294
  filter: var(--toggle-active-filter, var(--clickable-active-filter, var(--active-filter, brightness(0.9))));
270
295
  transform: var(--toggle-active-transform, var(--clickable-active-transform, var(--active-transform, none)));
271
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
296
+ background-color: color-mix(in oklab, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
272
297
  box-shadow: var(--toggle-active-box-shadow, var(--clickable-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none))));
273
298
  }
274
299
 
@@ -313,6 +313,31 @@ let popoverDiv = $state();
313
313
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
314
314
  has to happen where the real element is, in the global consumer rule; only
315
315
  the VALUES move to context vars here. */
316
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
317
+ that sits in the DOM wherever its trigger was placed.
318
+
319
+ The top layer changes how an element paints and where it is positioned, not
320
+ what it inherits. A popover declared inside a `white-space: nowrap` table
321
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
322
+ bold, uppercase and centred -- styles that belong to the trigger's context,
323
+ not to the overlay. typography-props() doesn't stop that: its chains end in
324
+ `unset`, which for an inherited property means "take the parent's value".
325
+
326
+ So this re-declares every inherited text property with a real default at
327
+ the end of the same variable chain. The vars still win (--tooltip-*, then
328
+ the category, then the global), and custom properties still inherit --
329
+ that is how theming reaches an overlay -- but when nothing is set, the
330
+ overlay gets its own defaults instead of its host's.
331
+
332
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
333
+ same rule: it has to beat their `unset` fallbacks by source order.
334
+
335
+ Deliberately left inheriting:
336
+ - direction, writing-mode: the document's script direction is the
337
+ overlay's too.
338
+ - visibility: a hidden subtree should not be able to show an overlay.
339
+ - font-family: every theme defines --font-family at :root, and there is no
340
+ neutral value to fall back to that would beat "the page's font". */
316
341
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
317
342
  one value (both sides equal) or two (start end), so there is no separate
318
343
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -445,14 +470,14 @@ button:hover {
445
470
  filter: var(--menu-trigger-hover-filter, var(--menu-hover-filter, var(--button-hover-filter, var(--control-hover-filter, var(--hover-filter, brightness(1.05))))));
446
471
  transform: var(--menu-trigger-hover-transform, var(--menu-hover-transform, var(--button-hover-transform, var(--control-hover-transform, var(--hover-transform, none)))));
447
472
  color: var(--_color);
448
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
473
+ background-color: color-mix(in oklab, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, var(--_color, white)) calc(100% - var(--hover-base-color-percentage, 90%)));
449
474
  box-shadow: var(--menu-trigger-hover-box-shadow, var(--menu-hover-box-shadow, var(--button-hover-box-shadow, var(--control-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none))))));
450
475
  }
451
476
 
452
477
  button:active {
453
478
  filter: var(--menu-trigger-active-filter, var(--menu-active-filter, var(--button-active-filter, var(--control-active-filter, var(--active-filter, brightness(0.9))))));
454
479
  transform: var(--menu-trigger-active-transform, var(--menu-active-transform, var(--button-active-transform, var(--control-active-transform, var(--active-transform, none)))));
455
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
480
+ background-color: color-mix(in oklab, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
456
481
  box-shadow: var(--menu-trigger-active-box-shadow, var(--menu-active-box-shadow, var(--button-active-box-shadow, var(--control-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none))))));
457
482
  }
458
483
 
@@ -460,7 +485,7 @@ button:disabled {
460
485
  cursor: var(--menu-trigger-disabled-cursor, var(--menu-disabled-cursor, var(--button-disabled-cursor, var(--control-disabled-cursor, var(--disabled-cursor, not-allowed)))));
461
486
  transform: var(--menu-trigger-disabled-transform, var(--menu-disabled-transform, var(--button-disabled-transform, var(--control-disabled-transform, var(--disabled-transform, none)))));
462
487
  filter: var(--menu-trigger-disabled-filter, var(--menu-disabled-filter, var(--button-disabled-filter, var(--control-disabled-filter, var(--disabled-filter, grayscale(0.5))))));
463
- background-color: color-mix(in oklch, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
488
+ background-color: color-mix(in oklab, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
464
489
  box-shadow: var(--menu-trigger-disabled-box-shadow, var(--menu-disabled-box-shadow, var(--button-disabled-box-shadow, var(--control-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none))))));
465
490
  }
466
491
 
@@ -584,14 +609,14 @@ button {
584
609
  filter: var(--menu-hover-filter, var(--button-hover-filter, var(--control-hover-filter, var(--hover-filter, brightness(1.05)))));
585
610
  transform: var(--menu-hover-transform, var(--button-hover-transform, var(--control-hover-transform, var(--hover-transform, none))));
586
611
  color: var(--_color);
587
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
612
+ background-color: color-mix(in oklab, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, var(--_color, white)) calc(100% - var(--hover-base-color-percentage, 90%)));
588
613
  box-shadow: var(--menu-hover-box-shadow, var(--button-hover-box-shadow, var(--control-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)))));
589
614
  }
590
615
 
591
616
  .dropdown-content :global(.menu):active {
592
617
  filter: var(--menu-active-filter, var(--button-active-filter, var(--control-active-filter, var(--active-filter, brightness(0.9)))));
593
618
  transform: var(--menu-active-transform, var(--button-active-transform, var(--control-active-transform, var(--active-transform, none))));
594
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
619
+ background-color: color-mix(in oklab, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
595
620
  box-shadow: var(--menu-active-box-shadow, var(--button-active-box-shadow, var(--control-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)))));
596
621
  }
597
622
 
@@ -599,7 +624,7 @@ button {
599
624
  cursor: var(--menu-disabled-cursor, var(--button-disabled-cursor, var(--control-disabled-cursor, var(--disabled-cursor, not-allowed))));
600
625
  transform: var(--menu-disabled-transform, var(--button-disabled-transform, var(--control-disabled-transform, var(--disabled-transform, none))));
601
626
  filter: var(--menu-disabled-filter, var(--button-disabled-filter, var(--control-disabled-filter, var(--disabled-filter, grayscale(0.5)))));
602
- background-color: color-mix(in oklch, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
627
+ background-color: color-mix(in oklab, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
603
628
  box-shadow: var(--menu-disabled-box-shadow, var(--button-disabled-box-shadow, var(--control-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)))));
604
629
  }
605
630
 
@@ -630,6 +655,35 @@ button {
630
655
  }
631
656
 
632
657
  .dropdown-container {
658
+ /* The popover is a DOM child of the <nav>, which sits wherever the menu
659
+ was placed; stop that spot's white-space, alignment, weight etc. from
660
+ reaching the list. First, so pointer-events below still wins. The
661
+ menu's own typography vars still apply to .menu inside. */
662
+ --_font-size: var(--dropdown-menu-font-size, var(--menu-font-size, var(--surface-font-size, var(--font-size, 1rem))));
663
+ font-size: var(--_font-size);
664
+ font-weight: var(--dropdown-menu-font-weight, var(--menu-font-weight, var(--surface-font-weight, var(--font-weight, normal))));
665
+ font-style: var(--dropdown-menu-font-style, var(--menu-font-style, var(--surface-font-style, var(--font-style, normal))));
666
+ font-variant: var(--dropdown-menu-font-variant, var(--menu-font-variant, var(--surface-font-variant, var(--font-variant, normal))));
667
+ font-feature-settings: normal;
668
+ text-transform: var(--dropdown-menu-text-transform, var(--menu-text-transform, var(--surface-text-transform, var(--text-transform, none))));
669
+ letter-spacing: var(--dropdown-menu-letter-spacing, var(--menu-letter-spacing, var(--surface-letter-spacing, var(--letter-spacing, normal))));
670
+ word-spacing: normal;
671
+ line-height: var(--dropdown-menu-line-height, var(--menu-line-height, var(--surface-line-height, var(--line-height, normal))));
672
+ text-indent: var(--dropdown-menu-indent, var(--menu-indent, var(--surface-indent, var(--indent, 0))));
673
+ text-align: var(--dropdown-menu-text-align, var(--menu-text-align, var(--surface-text-align, var(--text-align, start))));
674
+ text-shadow: none;
675
+ /* An overlay is capped by a max-width; its text has to wrap inside it. */
676
+ white-space: var(--dropdown-menu-white-space, var(--menu-white-space, var(--surface-white-space, var(--white-space, normal))));
677
+ word-break: normal;
678
+ overflow-wrap: var(--dropdown-menu-overflow-wrap, var(--menu-overflow-wrap, var(--surface-overflow-wrap, var(--overflow-wrap, break-word))));
679
+ hyphens: manual;
680
+ /* Not the trigger's pointer/text cursor, and never click-through. */
681
+ cursor: auto;
682
+ pointer-events: auto;
683
+ /* user-select isn't inherited, but `auto` copies a parent's `none`;
684
+ `text` is what `auto` resolves to in an ordinary context. */
685
+ -webkit-user-select: text;
686
+ user-select: text;
633
687
  box-sizing: border-box;
634
688
  opacity: 0;
635
689
  pointer-events: none;
@@ -79,6 +79,31 @@ function onAccordionClicked(e) {
79
79
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
80
80
  has to happen where the real element is, in the global consumer rule; only
81
81
  the VALUES move to context vars here. */
82
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
83
+ that sits in the DOM wherever its trigger was placed.
84
+
85
+ The top layer changes how an element paints and where it is positioned, not
86
+ what it inherits. A popover declared inside a `white-space: nowrap` table
87
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
88
+ bold, uppercase and centred -- styles that belong to the trigger's context,
89
+ not to the overlay. typography-props() doesn't stop that: its chains end in
90
+ `unset`, which for an inherited property means "take the parent's value".
91
+
92
+ So this re-declares every inherited text property with a real default at
93
+ the end of the same variable chain. The vars still win (--tooltip-*, then
94
+ the category, then the global), and custom properties still inherit --
95
+ that is how theming reaches an overlay -- but when nothing is set, the
96
+ overlay gets its own defaults instead of its host's.
97
+
98
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
99
+ same rule: it has to beat their `unset` fallbacks by source order.
100
+
101
+ Deliberately left inheriting:
102
+ - direction, writing-mode: the document's script direction is the
103
+ overlay's too.
104
+ - visibility: a hidden subtree should not be able to show an overlay.
105
+ - font-family: every theme defines --font-family at :root, and there is no
106
+ neutral value to fall back to that would beat "the page's font". */
82
107
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
83
108
  one value (both sides equal) or two (start end), so there is no separate
84
109
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -330,14 +355,14 @@ div :global(details > summary):hover {
330
355
  filter: var(--accordion-hover-filter, var(--hover-filter, brightness(1.05)));
331
356
  transform: var(--accordion-hover-transform, var(--hover-transform, none));
332
357
  color: var(--_color);
333
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
358
+ background-color: color-mix(in oklab, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, var(--_color, white)) calc(100% - var(--hover-base-color-percentage, 90%)));
334
359
  box-shadow: var(--accordion-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
335
360
  }
336
361
 
337
362
  div :global(details > summary):active {
338
363
  filter: var(--accordion-active-filter, var(--active-filter, brightness(0.9)));
339
364
  transform: var(--accordion-active-transform, var(--active-transform, none));
340
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
365
+ background-color: color-mix(in oklab, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
341
366
  box-shadow: var(--accordion-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)));
342
367
  }
343
368
 
@@ -345,7 +370,7 @@ div :global(details > summary):disabled {
345
370
  cursor: var(--accordion-disabled-cursor, var(--disabled-cursor, not-allowed));
346
371
  transform: var(--accordion-disabled-transform, var(--disabled-transform, none));
347
372
  filter: var(--accordion-disabled-filter, var(--disabled-filter, grayscale(0.5)));
348
- background-color: color-mix(in oklch, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
373
+ background-color: color-mix(in oklab, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
349
374
  box-shadow: var(--accordion-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)));
350
375
  }
351
376
 
@@ -74,6 +74,31 @@ const el = $derived(elementProps({ ...restProps, marginTop, marginBottom }, "bar
74
74
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
75
75
  has to happen where the real element is, in the global consumer rule; only
76
76
  the VALUES move to context vars here. */
77
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
78
+ that sits in the DOM wherever its trigger was placed.
79
+
80
+ The top layer changes how an element paints and where it is positioned, not
81
+ what it inherits. A popover declared inside a `white-space: nowrap` table
82
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
83
+ bold, uppercase and centred -- styles that belong to the trigger's context,
84
+ not to the overlay. typography-props() doesn't stop that: its chains end in
85
+ `unset`, which for an inherited property means "take the parent's value".
86
+
87
+ So this re-declares every inherited text property with a real default at
88
+ the end of the same variable chain. The vars still win (--tooltip-*, then
89
+ the category, then the global), and custom properties still inherit --
90
+ that is how theming reaches an overlay -- but when nothing is set, the
91
+ overlay gets its own defaults instead of its host's.
92
+
93
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
94
+ same rule: it has to beat their `unset` fallbacks by source order.
95
+
96
+ Deliberately left inheriting:
97
+ - direction, writing-mode: the document's script direction is the
98
+ overlay's too.
99
+ - visibility: a hidden subtree should not be able to show an overlay.
100
+ - font-family: every theme defines --font-family at :root, and there is no
101
+ neutral value to fall back to that would beat "the page's font". */
77
102
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
78
103
  one value (both sides equal) or two (start end), so there is no separate
79
104
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -47,6 +47,31 @@ const el = $derived(elementProps(restProps, "column-container", COLUMN_CONTAINER
47
47
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
48
48
  has to happen where the real element is, in the global consumer rule; only
49
49
  the VALUES move to context vars here. */
50
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
51
+ that sits in the DOM wherever its trigger was placed.
52
+
53
+ The top layer changes how an element paints and where it is positioned, not
54
+ what it inherits. A popover declared inside a `white-space: nowrap` table
55
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
56
+ bold, uppercase and centred -- styles that belong to the trigger's context,
57
+ not to the overlay. typography-props() doesn't stop that: its chains end in
58
+ `unset`, which for an inherited property means "take the parent's value".
59
+
60
+ So this re-declares every inherited text property with a real default at
61
+ the end of the same variable chain. The vars still win (--tooltip-*, then
62
+ the category, then the global), and custom properties still inherit --
63
+ that is how theming reaches an overlay -- but when nothing is set, the
64
+ overlay gets its own defaults instead of its host's.
65
+
66
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
67
+ same rule: it has to beat their `unset` fallbacks by source order.
68
+
69
+ Deliberately left inheriting:
70
+ - direction, writing-mode: the document's script direction is the
71
+ overlay's too.
72
+ - visibility: a hidden subtree should not be able to show an overlay.
73
+ - font-family: every theme defines --font-family at :root, and there is no
74
+ neutral value to fall back to that would beat "the page's font". */
50
75
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
51
76
  one value (both sides equal) or two (start end), so there is no separate
52
77
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -33,6 +33,31 @@ const el = $derived(elementProps(restProps, "columns", ["gap"]));
33
33
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
34
34
  has to happen where the real element is, in the global consumer rule; only
35
35
  the VALUES move to context vars here. */
36
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
37
+ that sits in the DOM wherever its trigger was placed.
38
+
39
+ The top layer changes how an element paints and where it is positioned, not
40
+ what it inherits. A popover declared inside a `white-space: nowrap` table
41
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
42
+ bold, uppercase and centred -- styles that belong to the trigger's context,
43
+ not to the overlay. typography-props() doesn't stop that: its chains end in
44
+ `unset`, which for an inherited property means "take the parent's value".
45
+
46
+ So this re-declares every inherited text property with a real default at
47
+ the end of the same variable chain. The vars still win (--tooltip-*, then
48
+ the category, then the global), and custom properties still inherit --
49
+ that is how theming reaches an overlay -- but when nothing is set, the
50
+ overlay gets its own defaults instead of its host's.
51
+
52
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
53
+ same rule: it has to beat their `unset` fallbacks by source order.
54
+
55
+ Deliberately left inheriting:
56
+ - direction, writing-mode: the document's script direction is the
57
+ overlay's too.
58
+ - visibility: a hidden subtree should not be able to show an overlay.
59
+ - font-family: every theme defines --font-family at :root, and there is no
60
+ neutral value to fall back to that would beat "the page's font". */
36
61
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
37
62
  one value (both sides equal) or two (start end), so there is no separate
38
63
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -51,6 +51,31 @@ const el = $derived(elementProps(restProps, "container", [
51
51
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
52
52
  has to happen where the real element is, in the global consumer rule; only
53
53
  the VALUES move to context vars here. */
54
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
55
+ that sits in the DOM wherever its trigger was placed.
56
+
57
+ The top layer changes how an element paints and where it is positioned, not
58
+ what it inherits. A popover declared inside a `white-space: nowrap` table
59
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
60
+ bold, uppercase and centred -- styles that belong to the trigger's context,
61
+ not to the overlay. typography-props() doesn't stop that: its chains end in
62
+ `unset`, which for an inherited property means "take the parent's value".
63
+
64
+ So this re-declares every inherited text property with a real default at
65
+ the end of the same variable chain. The vars still win (--tooltip-*, then
66
+ the category, then the global), and custom properties still inherit --
67
+ that is how theming reaches an overlay -- but when nothing is set, the
68
+ overlay gets its own defaults instead of its host's.
69
+
70
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
71
+ same rule: it has to beat their `unset` fallbacks by source order.
72
+
73
+ Deliberately left inheriting:
74
+ - direction, writing-mode: the document's script direction is the
75
+ overlay's too.
76
+ - visibility: a hidden subtree should not be able to show an overlay.
77
+ - font-family: every theme defines --font-family at :root, and there is no
78
+ neutral value to fall back to that would beat "the page's font". */
54
79
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
55
80
  one value (both sides equal) or two (start end), so there is no separate
56
81
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -70,6 +70,31 @@ const el = $derived(elementProps(restProps, "data-list", [
70
70
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
71
71
  has to happen where the real element is, in the global consumer rule; only
72
72
  the VALUES move to context vars here. */
73
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
74
+ that sits in the DOM wherever its trigger was placed.
75
+
76
+ The top layer changes how an element paints and where it is positioned, not
77
+ what it inherits. A popover declared inside a `white-space: nowrap` table
78
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
79
+ bold, uppercase and centred -- styles that belong to the trigger's context,
80
+ not to the overlay. typography-props() doesn't stop that: its chains end in
81
+ `unset`, which for an inherited property means "take the parent's value".
82
+
83
+ So this re-declares every inherited text property with a real default at
84
+ the end of the same variable chain. The vars still win (--tooltip-*, then
85
+ the category, then the global), and custom properties still inherit --
86
+ that is how theming reaches an overlay -- but when nothing is set, the
87
+ overlay gets its own defaults instead of its host's.
88
+
89
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
90
+ same rule: it has to beat their `unset` fallbacks by source order.
91
+
92
+ Deliberately left inheriting:
93
+ - direction, writing-mode: the document's script direction is the
94
+ overlay's too.
95
+ - visibility: a hidden subtree should not be able to show an overlay.
96
+ - font-family: every theme defines --font-family at :root, and there is no
97
+ neutral value to fall back to that would beat "the page's font". */
73
98
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
74
99
  one value (both sides equal) or two (start end), so there is no separate
75
100
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -148,6 +148,31 @@ function handleKeydown(event) {
148
148
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
149
149
  has to happen where the real element is, in the global consumer rule; only
150
150
  the VALUES move to context vars here. */
151
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
152
+ that sits in the DOM wherever its trigger was placed.
153
+
154
+ The top layer changes how an element paints and where it is positioned, not
155
+ what it inherits. A popover declared inside a `white-space: nowrap` table
156
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
157
+ bold, uppercase and centred -- styles that belong to the trigger's context,
158
+ not to the overlay. typography-props() doesn't stop that: its chains end in
159
+ `unset`, which for an inherited property means "take the parent's value".
160
+
161
+ So this re-declares every inherited text property with a real default at
162
+ the end of the same variable chain. The vars still win (--tooltip-*, then
163
+ the category, then the global), and custom properties still inherit --
164
+ that is how theming reaches an overlay -- but when nothing is set, the
165
+ overlay gets its own defaults instead of its host's.
166
+
167
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
168
+ same rule: it has to beat their `unset` fallbacks by source order.
169
+
170
+ Deliberately left inheriting:
171
+ - direction, writing-mode: the document's script direction is the
172
+ overlay's too.
173
+ - visibility: a hidden subtree should not be able to show an overlay.
174
+ - font-family: every theme defines --font-family at :root, and there is no
175
+ neutral value to fall back to that would beat "the page's font". */
151
176
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
152
177
  one value (both sides equal) or two (start end), so there is no separate
153
178
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -568,14 +593,14 @@ function handleKeydown(event) {
568
593
  filter: var(--data-list-item-hover-filter, var(--hover-filter, brightness(1.05)));
569
594
  transform: var(--data-list-item-hover-transform, var(--hover-transform, none));
570
595
  color: var(--_color);
571
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
596
+ background-color: color-mix(in oklab, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, var(--_color, white)) calc(100% - var(--hover-base-color-percentage, 90%)));
572
597
  box-shadow: var(--data-list-item-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
573
598
  }
574
599
 
575
600
  .data-list-item.isInteractive:active {
576
601
  filter: var(--data-list-item-active-filter, var(--active-filter, brightness(0.9)));
577
602
  transform: var(--data-list-item-active-transform, var(--active-transform, none));
578
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
603
+ background-color: color-mix(in oklab, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
579
604
  box-shadow: var(--data-list-item-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)));
580
605
  }
581
606
 
@@ -583,7 +608,7 @@ function handleKeydown(event) {
583
608
  cursor: var(--data-list-item-disabled-cursor, var(--disabled-cursor, not-allowed));
584
609
  transform: var(--data-list-item-disabled-transform, var(--disabled-transform, none));
585
610
  filter: var(--data-list-item-disabled-filter, var(--disabled-filter, grayscale(0.5)));
586
- background-color: color-mix(in oklch, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
611
+ background-color: color-mix(in oklab, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
587
612
  box-shadow: var(--data-list-item-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)));
588
613
  }
589
614