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
@@ -80,6 +80,31 @@ const el = $derived(elementProps({
80
80
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
81
81
  has to happen where the real element is, in the global consumer rule; only
82
82
  the VALUES move to context vars here. */
83
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
84
+ that sits in the DOM wherever its trigger was placed.
85
+
86
+ The top layer changes how an element paints and where it is positioned, not
87
+ what it inherits. A popover declared inside a `white-space: nowrap` table
88
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
89
+ bold, uppercase and centred -- styles that belong to the trigger's context,
90
+ not to the overlay. typography-props() doesn't stop that: its chains end in
91
+ `unset`, which for an inherited property means "take the parent's value".
92
+
93
+ So this re-declares every inherited text property with a real default at
94
+ the end of the same variable chain. The vars still win (--tooltip-*, then
95
+ the category, then the global), and custom properties still inherit --
96
+ that is how theming reaches an overlay -- but when nothing is set, the
97
+ overlay gets its own defaults instead of its host's.
98
+
99
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
100
+ same rule: it has to beat their `unset` fallbacks by source order.
101
+
102
+ Deliberately left inheriting:
103
+ - direction, writing-mode: the document's script direction is the
104
+ overlay's too.
105
+ - visibility: a hidden subtree should not be able to show an overlay.
106
+ - font-family: every theme defines --font-family at :root, and there is no
107
+ neutral value to fall back to that would beat "the page's font". */
83
108
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
84
109
  one value (both sides equal) or two (start end), so there is no separate
85
110
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -78,6 +78,31 @@ const el = $derived(elementProps({
78
78
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
79
79
  has to happen where the real element is, in the global consumer rule; only
80
80
  the VALUES move to context vars here. */
81
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
82
+ that sits in the DOM wherever its trigger was placed.
83
+
84
+ The top layer changes how an element paints and where it is positioned, not
85
+ what it inherits. A popover declared inside a `white-space: nowrap` table
86
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
87
+ bold, uppercase and centred -- styles that belong to the trigger's context,
88
+ not to the overlay. typography-props() doesn't stop that: its chains end in
89
+ `unset`, which for an inherited property means "take the parent's value".
90
+
91
+ So this re-declares every inherited text property with a real default at
92
+ the end of the same variable chain. The vars still win (--tooltip-*, then
93
+ the category, then the global), and custom properties still inherit --
94
+ that is how theming reaches an overlay -- but when nothing is set, the
95
+ overlay gets its own defaults instead of its host's.
96
+
97
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
98
+ same rule: it has to beat their `unset` fallbacks by source order.
99
+
100
+ Deliberately left inheriting:
101
+ - direction, writing-mode: the document's script direction is the
102
+ overlay's too.
103
+ - visibility: a hidden subtree should not be able to show an overlay.
104
+ - font-family: every theme defines --font-family at :root, and there is no
105
+ neutral value to fall back to that would beat "the page's font". */
81
106
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
82
107
  one value (both sides equal) or two (start end), so there is no separate
83
108
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -67,6 +67,31 @@ const effectiveLayout = $derived(above ? "above" : below ? "below" : effectiveLa
67
67
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
68
68
  has to happen where the real element is, in the global consumer rule; only
69
69
  the VALUES move to context vars here. */
70
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
71
+ that sits in the DOM wherever its trigger was placed.
72
+
73
+ The top layer changes how an element paints and where it is positioned, not
74
+ what it inherits. A popover declared inside a `white-space: nowrap` table
75
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
76
+ bold, uppercase and centred -- styles that belong to the trigger's context,
77
+ not to the overlay. typography-props() doesn't stop that: its chains end in
78
+ `unset`, which for an inherited property means "take the parent's value".
79
+
80
+ So this re-declares every inherited text property with a real default at
81
+ the end of the same variable chain. The vars still win (--tooltip-*, then
82
+ the category, then the global), and custom properties still inherit --
83
+ that is how theming reaches an overlay -- but when nothing is set, the
84
+ overlay gets its own defaults instead of its host's.
85
+
86
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
87
+ same rule: it has to beat their `unset` fallbacks by source order.
88
+
89
+ Deliberately left inheriting:
90
+ - direction, writing-mode: the document's script direction is the
91
+ overlay's too.
92
+ - visibility: a hidden subtree should not be able to show an overlay.
93
+ - font-family: every theme defines --font-family at :root, and there is no
94
+ neutral value to fall back to that would beat "the page's font". */
70
95
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
71
96
  one value (both sides equal) or two (start end), so there is no separate
72
97
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -48,6 +48,31 @@ const el = $derived(elementProps(restProps, "grid-layout", GRID_LAYOUT_VARS));
48
48
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
49
49
  has to happen where the real element is, in the global consumer rule; only
50
50
  the VALUES move to context vars here. */
51
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
52
+ that sits in the DOM wherever its trigger was placed.
53
+
54
+ The top layer changes how an element paints and where it is positioned, not
55
+ what it inherits. A popover declared inside a `white-space: nowrap` table
56
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
57
+ bold, uppercase and centred -- styles that belong to the trigger's context,
58
+ not to the overlay. typography-props() doesn't stop that: its chains end in
59
+ `unset`, which for an inherited property means "take the parent's value".
60
+
61
+ So this re-declares every inherited text property with a real default at
62
+ the end of the same variable chain. The vars still win (--tooltip-*, then
63
+ the category, then the global), and custom properties still inherit --
64
+ that is how theming reaches an overlay -- but when nothing is set, the
65
+ overlay gets its own defaults instead of its host's.
66
+
67
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
68
+ same rule: it has to beat their `unset` fallbacks by source order.
69
+
70
+ Deliberately left inheriting:
71
+ - direction, writing-mode: the document's script direction is the
72
+ overlay's too.
73
+ - visibility: a hidden subtree should not be able to show an overlay.
74
+ - font-family: every theme defines --font-family at :root, and there is no
75
+ neutral value to fall back to that would beat "the page's font". */
51
76
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
52
77
  one value (both sides equal) or two (start end), so there is no separate
53
78
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -52,6 +52,31 @@ const el = $derived(elementProps(restProps, "hero", [
52
52
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
53
53
  has to happen where the real element is, in the global consumer rule; only
54
54
  the VALUES move to context vars here. */
55
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
56
+ that sits in the DOM wherever its trigger was placed.
57
+
58
+ The top layer changes how an element paints and where it is positioned, not
59
+ what it inherits. A popover declared inside a `white-space: nowrap` table
60
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
61
+ bold, uppercase and centred -- styles that belong to the trigger's context,
62
+ not to the overlay. typography-props() doesn't stop that: its chains end in
63
+ `unset`, which for an inherited property means "take the parent's value".
64
+
65
+ So this re-declares every inherited text property with a real default at
66
+ the end of the same variable chain. The vars still win (--tooltip-*, then
67
+ the category, then the global), and custom properties still inherit --
68
+ that is how theming reaches an overlay -- but when nothing is set, the
69
+ overlay gets its own defaults instead of its host's.
70
+
71
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
72
+ same rule: it has to beat their `unset` fallbacks by source order.
73
+
74
+ Deliberately left inheriting:
75
+ - direction, writing-mode: the document's script direction is the
76
+ overlay's too.
77
+ - visibility: a hidden subtree should not be able to show an overlay.
78
+ - font-family: every theme defines --font-family at :root, and there is no
79
+ neutral value to fall back to that would beat "the page's font". */
55
80
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
56
81
  one value (both sides equal) or two (start end), so there is no separate
57
82
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -370,11 +395,21 @@ const el = $derived(elementProps(restProps, "hero", [
370
395
  height: var(--hero-height, 100vh);
371
396
  /* font-size: var(--hero-font-size, 2rem); */
372
397
  box-sizing: border-box;
398
+ }
399
+
400
+ /* Fade the content, not the hero itself: fading the whole block makes its
401
+ background flash in over the page on every load. */
402
+ .hero > :global(*) {
373
403
  animation-name: fade-in;
374
404
  animation-duration: var(--hero-animation-duration, 1s);
375
405
  animation-timing-function: var(--hero-animation-timing-function, ease-in-out);
376
406
  }
377
407
 
408
+ @media (prefers-reduced-motion: reduce) {
409
+ .hero > :global(*) {
410
+ animation: none;
411
+ }
412
+ }
378
413
  @keyframes fade-in {
379
414
  0% {
380
415
  filter: blur(3px);
@@ -58,6 +58,31 @@ const el = $derived(elementProps({ justify, align, gap, wrap, ...restProps }, "i
58
58
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
59
59
  has to happen where the real element is, in the global consumer rule; only
60
60
  the VALUES move to context vars here. */
61
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
62
+ that sits in the DOM wherever its trigger was placed.
63
+
64
+ The top layer changes how an element paints and where it is positioned, not
65
+ what it inherits. A popover declared inside a `white-space: nowrap` table
66
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
67
+ bold, uppercase and centred -- styles that belong to the trigger's context,
68
+ not to the overlay. typography-props() doesn't stop that: its chains end in
69
+ `unset`, which for an inherited property means "take the parent's value".
70
+
71
+ So this re-declares every inherited text property with a real default at
72
+ the end of the same variable chain. The vars still win (--tooltip-*, then
73
+ the category, then the global), and custom properties still inherit --
74
+ that is how theming reaches an overlay -- but when nothing is set, the
75
+ overlay gets its own defaults instead of its host's.
76
+
77
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
78
+ same rule: it has to beat their `unset` fallbacks by source order.
79
+
80
+ Deliberately left inheriting:
81
+ - direction, writing-mode: the document's script direction is the
82
+ overlay's too.
83
+ - visibility: a hidden subtree should not be able to show an overlay.
84
+ - font-family: every theme defines --font-family at :root, and there is no
85
+ neutral value to fall back to that would beat "the page's font". */
61
86
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
62
87
  one value (both sides equal) or two (start end), so there is no separate
63
88
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -52,6 +52,31 @@ const el = $derived(elementProps(restProps, "menu", [
52
52
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
53
53
  has to happen where the real element is, in the global consumer rule; only
54
54
  the VALUES move to context vars here. */
55
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
56
+ that sits in the DOM wherever its trigger was placed.
57
+
58
+ The top layer changes how an element paints and where it is positioned, not
59
+ what it inherits. A popover declared inside a `white-space: nowrap` table
60
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
61
+ bold, uppercase and centred -- styles that belong to the trigger's context,
62
+ not to the overlay. typography-props() doesn't stop that: its chains end in
63
+ `unset`, which for an inherited property means "take the parent's value".
64
+
65
+ So this re-declares every inherited text property with a real default at
66
+ the end of the same variable chain. The vars still win (--tooltip-*, then
67
+ the category, then the global), and custom properties still inherit --
68
+ that is how theming reaches an overlay -- but when nothing is set, the
69
+ overlay gets its own defaults instead of its host's.
70
+
71
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
72
+ same rule: it has to beat their `unset` fallbacks by source order.
73
+
74
+ Deliberately left inheriting:
75
+ - direction, writing-mode: the document's script direction is the
76
+ overlay's too.
77
+ - visibility: a hidden subtree should not be able to show an overlay.
78
+ - font-family: every theme defines --font-family at :root, and there is no
79
+ neutral value to fall back to that would beat "the page's font". */
55
80
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
56
81
  one value (both sides equal) or two (start end), so there is no separate
57
82
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -185,14 +210,14 @@ const el = $derived(elementProps(restProps, "menu", [
185
210
  filter: var(--menu-item-hover-filter, var(--hover-filter, brightness(1.05)));
186
211
  transform: var(--menu-item-hover-transform, var(--hover-transform, none));
187
212
  color: var(--_color);
188
- 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%)));
213
+ 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%)));
189
214
  box-shadow: var(--menu-item-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
190
215
  }
191
216
 
192
217
  .menu :global(li):active {
193
218
  filter: var(--menu-item-active-filter, var(--active-filter, brightness(0.9)));
194
219
  transform: var(--menu-item-active-transform, var(--active-transform, none));
195
- 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%)));
220
+ 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%)));
196
221
  box-shadow: var(--menu-item-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)));
197
222
  }
198
223
 
@@ -200,7 +225,7 @@ const el = $derived(elementProps(restProps, "menu", [
200
225
  cursor: var(--menu-item-disabled-cursor, var(--disabled-cursor, not-allowed));
201
226
  transform: var(--menu-item-disabled-transform, var(--disabled-transform, none));
202
227
  filter: var(--menu-item-disabled-filter, var(--disabled-filter, grayscale(0.5)));
203
- 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%)));
228
+ 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%)));
204
229
  box-shadow: var(--menu-item-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)));
205
230
  }
206
231
 
@@ -230,7 +255,7 @@ const el = $derived(elementProps(restProps, "menu", [
230
255
  filter: var(--menu-item-hover-filter, var(--hover-filter, brightness(1.05)));
231
256
  transform: var(--menu-item-hover-transform, var(--hover-transform, none));
232
257
  color: var(--_color);
233
- 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%)));
258
+ 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%)));
234
259
  box-shadow: var(--menu-item-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
235
260
  }
236
261
 
@@ -241,7 +266,7 @@ const el = $derived(elementProps(restProps, "menu", [
241
266
  .menu :global(li[tabindex]:not([tabindex="-1"])):active {
242
267
  filter: var(--menu-item-active-filter, var(--active-filter, brightness(0.9)));
243
268
  transform: var(--menu-item-active-transform, var(--active-transform, none));
244
- 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%)));
269
+ 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%)));
245
270
  box-shadow: var(--menu-item-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)));
246
271
  }
247
272
 
@@ -253,7 +278,7 @@ const el = $derived(elementProps(restProps, "menu", [
253
278
  cursor: var(--menu-item-disabled-cursor, var(--disabled-cursor, not-allowed));
254
279
  transform: var(--menu-item-disabled-transform, var(--disabled-transform, none));
255
280
  filter: var(--menu-item-disabled-filter, var(--disabled-filter, grayscale(0.5)));
256
- 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%)));
281
+ 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%)));
257
282
  box-shadow: var(--menu-item-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)));
258
283
  }
259
284
 
@@ -265,7 +290,7 @@ const el = $derived(elementProps(restProps, "menu", [
265
290
  filter: var(--menu-item-hover-filter, var(--hover-filter, brightness(1.05)));
266
291
  transform: var(--menu-item-hover-transform, var(--hover-transform, none));
267
292
  color: var(--_color);
268
- 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%)));
293
+ 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%)));
269
294
  box-shadow: var(--menu-item-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
270
295
  outline: var(--focus-color, -webkit-focus-ring-color) auto 1px;
271
296
  outline-offset: var(--focus-inset-outline-offset, -3px);
@@ -403,7 +428,7 @@ const el = $derived(elementProps(restProps, "menu", [
403
428
  filter: var(--menu-item-hover-filter, var(--hover-filter, brightness(1.05)));
404
429
  transform: var(--menu-item-hover-transform, var(--hover-transform, none));
405
430
  color: var(--_color);
406
- 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%)));
431
+ 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%)));
407
432
  box-shadow: var(--menu-item-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
408
433
  outline: var(--focus-color, -webkit-focus-ring-color) auto 1px;
409
434
  outline-offset: var(--focus-inset-outline-offset, -3px);
@@ -418,14 +443,14 @@ const el = $derived(elementProps(restProps, "menu", [
418
443
  filter: var(--menu-item-hover-filter, var(--hover-filter, brightness(1.05)));
419
444
  transform: var(--menu-item-hover-transform, var(--hover-transform, none));
420
445
  color: var(--_color);
421
- 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%)));
446
+ 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%)));
422
447
  box-shadow: var(--menu-item-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)));
423
448
  }
424
449
 
425
450
  .menu :global(a):active, .menu :global(button):active, .menu :global(input[type="submit"]):active, .menu :global(.button):active {
426
451
  filter: var(--menu-item-active-filter, var(--active-filter, brightness(0.9)));
427
452
  transform: var(--menu-item-active-transform, var(--active-transform, none));
428
- 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%)));
453
+ 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%)));
429
454
  box-shadow: var(--menu-item-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)));
430
455
  }
431
456
 
@@ -433,7 +458,7 @@ const el = $derived(elementProps(restProps, "menu", [
433
458
  cursor: var(--menu-item-disabled-cursor, var(--disabled-cursor, not-allowed));
434
459
  transform: var(--menu-item-disabled-transform, var(--disabled-transform, none));
435
460
  filter: var(--menu-item-disabled-filter, var(--disabled-filter, grayscale(0.5)));
436
- 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%)));
461
+ 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%)));
437
462
  box-shadow: var(--menu-item-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)));
438
463
  }
439
464
 
@@ -115,6 +115,31 @@ onMount(() => {
115
115
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
116
116
  has to happen where the real element is, in the global consumer rule; only
117
117
  the VALUES move to context vars here. */
118
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
119
+ that sits in the DOM wherever its trigger was placed.
120
+
121
+ The top layer changes how an element paints and where it is positioned, not
122
+ what it inherits. A popover declared inside a `white-space: nowrap` table
123
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
124
+ bold, uppercase and centred -- styles that belong to the trigger's context,
125
+ not to the overlay. typography-props() doesn't stop that: its chains end in
126
+ `unset`, which for an inherited property means "take the parent's value".
127
+
128
+ So this re-declares every inherited text property with a real default at
129
+ the end of the same variable chain. The vars still win (--tooltip-*, then
130
+ the category, then the global), and custom properties still inherit --
131
+ that is how theming reaches an overlay -- but when nothing is set, the
132
+ overlay gets its own defaults instead of its host's.
133
+
134
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
135
+ same rule: it has to beat their `unset` fallbacks by source order.
136
+
137
+ Deliberately left inheriting:
138
+ - direction, writing-mode: the document's script direction is the
139
+ overlay's too.
140
+ - visibility: a hidden subtree should not be able to show an overlay.
141
+ - font-family: every theme defines --font-family at :root, and there is no
142
+ neutral value to fall back to that would beat "the page's font". */
118
143
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
119
144
  one value (both sides equal) or two (start end), so there is no separate
120
145
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -47,6 +47,31 @@ const el = $derived(elementProps(restProps, "row-container", ROW_CONTAINER_VARS)
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.
@@ -85,6 +85,31 @@ const expandedHamburger = $derived(open ?? false);
85
85
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
86
86
  has to happen where the real element is, in the global consumer rule; only
87
87
  the VALUES move to context vars here. */
88
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
89
+ that sits in the DOM wherever its trigger was placed.
90
+
91
+ The top layer changes how an element paints and where it is positioned, not
92
+ what it inherits. A popover declared inside a `white-space: nowrap` table
93
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
94
+ bold, uppercase and centred -- styles that belong to the trigger's context,
95
+ not to the overlay. typography-props() doesn't stop that: its chains end in
96
+ `unset`, which for an inherited property means "take the parent's value".
97
+
98
+ So this re-declares every inherited text property with a real default at
99
+ the end of the same variable chain. The vars still win (--tooltip-*, then
100
+ the category, then the global), and custom properties still inherit --
101
+ that is how theming reaches an overlay -- but when nothing is set, the
102
+ overlay gets its own defaults instead of its host's.
103
+
104
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
105
+ same rule: it has to beat their `unset` fallbacks by source order.
106
+
107
+ Deliberately left inheriting:
108
+ - direction, writing-mode: the document's script direction is the
109
+ overlay's too.
110
+ - visibility: a hidden subtree should not be able to show an overlay.
111
+ - font-family: every theme defines --font-family at :root, and there is no
112
+ neutral value to fall back to that would beat "the page's font". */
88
113
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
89
114
  one value (both sides equal) or two (start end), so there is no separate
90
115
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -693,20 +718,20 @@ aside .content:hover::-webkit-scrollbar-thumb:hover {
693
718
  filter: var(--circle-button-hover-filter, var(--mini-button-hover-filter, var(--button-hover-filter, var(--control-hover-filter, var(--hover-filter, brightness(1.05))))));
694
719
  transform: var(--circle-button-hover-transform, var(--mini-button-hover-transform, var(--button-hover-transform, var(--control-hover-transform, var(--hover-transform, none)))));
695
720
  color: var(--_color);
696
- 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%)));
721
+ 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%)));
697
722
  box-shadow: var(--circle-button-hover-box-shadow, var(--mini-button-hover-box-shadow, var(--button-hover-box-shadow, var(--control-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none))))));
698
723
  }
699
724
  aside.overlay > button:active {
700
725
  filter: var(--circle-button-active-filter, var(--mini-button-active-filter, var(--button-active-filter, var(--control-active-filter, var(--active-filter, brightness(0.9))))));
701
726
  transform: var(--circle-button-active-transform, var(--mini-button-active-transform, var(--button-active-transform, var(--control-active-transform, var(--active-transform, none)))));
702
- 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%)));
727
+ 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%)));
703
728
  box-shadow: var(--circle-button-active-box-shadow, var(--mini-button-active-box-shadow, var(--button-active-box-shadow, var(--control-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none))))));
704
729
  }
705
730
  aside.overlay > button:disabled {
706
731
  cursor: var(--circle-button-disabled-cursor, var(--mini-button-disabled-cursor, var(--button-disabled-cursor, var(--control-disabled-cursor, var(--disabled-cursor, not-allowed)))));
707
732
  transform: var(--circle-button-disabled-transform, var(--mini-button-disabled-transform, var(--button-disabled-transform, var(--control-disabled-transform, var(--disabled-transform, none)))));
708
733
  filter: var(--circle-button-disabled-filter, var(--mini-button-disabled-filter, var(--button-disabled-filter, var(--control-disabled-filter, var(--disabled-filter, grayscale(0.5))))));
709
- 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%)));
734
+ 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%)));
710
735
  box-shadow: var(--circle-button-disabled-box-shadow, var(--mini-button-disabled-box-shadow, var(--button-disabled-box-shadow, var(--control-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none))))));
711
736
  }
712
737
  aside.overlay > button:focus-visible {
@@ -1272,20 +1297,20 @@ aside .content:hover::-webkit-scrollbar-thumb:hover {
1272
1297
  filter: var(--circle-button-hover-filter, var(--mini-button-hover-filter, var(--button-hover-filter, var(--control-hover-filter, var(--hover-filter, brightness(1.05))))));
1273
1298
  transform: var(--circle-button-hover-transform, var(--mini-button-hover-transform, var(--button-hover-transform, var(--control-hover-transform, var(--hover-transform, none)))));
1274
1299
  color: var(--_color);
1275
- 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%)));
1300
+ 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%)));
1276
1301
  box-shadow: var(--circle-button-hover-box-shadow, var(--mini-button-hover-box-shadow, var(--button-hover-box-shadow, var(--control-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none))))));
1277
1302
  }
1278
1303
  aside > button:active {
1279
1304
  filter: var(--circle-button-active-filter, var(--mini-button-active-filter, var(--button-active-filter, var(--control-active-filter, var(--active-filter, brightness(0.9))))));
1280
1305
  transform: var(--circle-button-active-transform, var(--mini-button-active-transform, var(--button-active-transform, var(--control-active-transform, var(--active-transform, none)))));
1281
- 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%)));
1306
+ 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%)));
1282
1307
  box-shadow: var(--circle-button-active-box-shadow, var(--mini-button-active-box-shadow, var(--button-active-box-shadow, var(--control-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none))))));
1283
1308
  }
1284
1309
  aside > button:disabled {
1285
1310
  cursor: var(--circle-button-disabled-cursor, var(--mini-button-disabled-cursor, var(--button-disabled-cursor, var(--control-disabled-cursor, var(--disabled-cursor, not-allowed)))));
1286
1311
  transform: var(--circle-button-disabled-transform, var(--mini-button-disabled-transform, var(--button-disabled-transform, var(--control-disabled-transform, var(--disabled-transform, none)))));
1287
1312
  filter: var(--circle-button-disabled-filter, var(--mini-button-disabled-filter, var(--button-disabled-filter, var(--control-disabled-filter, var(--disabled-filter, grayscale(0.5))))));
1288
- 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%)));
1313
+ 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%)));
1289
1314
  box-shadow: var(--circle-button-disabled-box-shadow, var(--mini-button-disabled-box-shadow, var(--button-disabled-box-shadow, var(--control-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none))))));
1290
1315
  }
1291
1316
  aside > button:focus-visible {
@@ -1460,7 +1485,12 @@ aside > button.close::after {
1460
1485
  background-image: var(--sidebar-sheet-collapse-image, var(--sidebar-collapse-image, none));
1461
1486
  }
1462
1487
 
1488
+ /* Mirrored, and still inline-grid from the rule above: the grid is what
1489
+ centres a glyph wider than its box (the sheet's menu glyph is, at the
1490
+ rail chevron's 0.65rem). An old `display: inline-block` here overrode
1491
+ it, so the glyph started at the box's left edge, spilled right, and the
1492
+ mirror threw the spill left -- every right-hand sheet button sat about
1493
+ 2.5px off centre. */
1463
1494
  .right button::after {
1464
- display: inline-block;
1465
1495
  transform: var(--mirror-sidebar-icons, scaleX(-1));
1466
1496
  }</style>
@@ -44,6 +44,31 @@ const el = $derived(elementProps(restProps, "sidebar-container", [
44
44
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
45
45
  has to happen where the real element is, in the global consumer rule; only
46
46
  the VALUES move to context vars here. */
47
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
48
+ that sits in the DOM wherever its trigger was placed.
49
+
50
+ The top layer changes how an element paints and where it is positioned, not
51
+ what it inherits. A popover declared inside a `white-space: nowrap` table
52
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
53
+ bold, uppercase and centred -- styles that belong to the trigger's context,
54
+ not to the overlay. typography-props() doesn't stop that: its chains end in
55
+ `unset`, which for an inherited property means "take the parent's value".
56
+
57
+ So this re-declares every inherited text property with a real default at
58
+ the end of the same variable chain. The vars still win (--tooltip-*, then
59
+ the category, then the global), and custom properties still inherit --
60
+ that is how theming reaches an overlay -- but when nothing is set, the
61
+ overlay gets its own defaults instead of its host's.
62
+
63
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
64
+ same rule: it has to beat their `unset` fallbacks by source order.
65
+
66
+ Deliberately left inheriting:
67
+ - direction, writing-mode: the document's script direction is the
68
+ overlay's too.
69
+ - visibility: a hidden subtree should not be able to show an overlay.
70
+ - font-family: every theme defines --font-family at :root, and there is no
71
+ neutral value to fall back to that would beat "the page's font". */
47
72
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
48
73
  one value (both sides equal) or two (start end), so there is no separate
49
74
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -142,6 +142,31 @@ onMount(() => {
142
142
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
143
143
  has to happen where the real element is, in the global consumer rule; only
144
144
  the VALUES move to context vars here. */
145
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
146
+ that sits in the DOM wherever its trigger was placed.
147
+
148
+ The top layer changes how an element paints and where it is positioned, not
149
+ what it inherits. A popover declared inside a `white-space: nowrap` table
150
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
151
+ bold, uppercase and centred -- styles that belong to the trigger's context,
152
+ not to the overlay. typography-props() doesn't stop that: its chains end in
153
+ `unset`, which for an inherited property means "take the parent's value".
154
+
155
+ So this re-declares every inherited text property with a real default at
156
+ the end of the same variable chain. The vars still win (--tooltip-*, then
157
+ the category, then the global), and custom properties still inherit --
158
+ that is how theming reaches an overlay -- but when nothing is set, the
159
+ overlay gets its own defaults instead of its host's.
160
+
161
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
162
+ same rule: it has to beat their `unset` fallbacks by source order.
163
+
164
+ Deliberately left inheriting:
165
+ - direction, writing-mode: the document's script direction is the
166
+ overlay's too.
167
+ - visibility: a hidden subtree should not be able to show an overlay.
168
+ - font-family: every theme defines --font-family at :root, and there is no
169
+ neutral value to fall back to that would beat "the page's font". */
145
170
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
146
171
  one value (both sides equal) or two (start end), so there is no separate
147
172
  "which side" prop to remember and no 4-value shorthand order to get wrong.
@@ -58,6 +58,31 @@ const el = $derived(elementProps({ justify, align: resolvedAlign, gap, ...restPr
58
58
  text, no top margin. Structural matching (:first-of-type, `h1 + p`) still
59
59
  has to happen where the real element is, in the global consumer rule; only
60
60
  the VALUES move to context vars here. */
61
+ /* Text reset for an overlay's root element: a tooltip, popover menu or dialog
62
+ that sits in the DOM wherever its trigger was placed.
63
+
64
+ The top layer changes how an element paints and where it is positioned, not
65
+ what it inherits. A popover declared inside a `white-space: nowrap` table
66
+ cell is nowrap too, and one inside a bold, uppercase, centred header is
67
+ bold, uppercase and centred -- styles that belong to the trigger's context,
68
+ not to the overlay. typography-props() doesn't stop that: its chains end in
69
+ `unset`, which for an inherited property means "take the parent's value".
70
+
71
+ So this re-declares every inherited text property with a real default at
72
+ the end of the same variable chain. The vars still win (--tooltip-*, then
73
+ the category, then the global), and custom properties still inherit --
74
+ that is how theming reaches an overlay -- but when nothing is set, the
75
+ overlay gets its own defaults instead of its host's.
76
+
77
+ INCLUDE IT AFTER typography-props() / typography-container-props() in the
78
+ same rule: it has to beat their `unset` fallbacks by source order.
79
+
80
+ Deliberately left inheriting:
81
+ - direction, writing-mode: the document's script direction is the
82
+ overlay's too.
83
+ - visibility: a hidden subtree should not be able to show an overlay.
84
+ - font-family: every theme defines --font-family at :root, and there is no
85
+ neutral value to fall back to that would beat "the page's font". */
61
86
  /* Logical, not top/bottom/left/right: margin-block/margin-inline already take
62
87
  one value (both sides equal) or two (start end), so there is no separate
63
88
  "which side" prop to remember and no 4-value shorthand order to get wrong.