@scattered-light/loomiere-mojave 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/exports/AGENTS.md +24 -8
  2. package/dist/exports/catalog.json +21 -0
  3. package/dist/exports/chakra.js +333 -0
  4. package/dist/exports/design-system/README.md +23 -7
  5. package/dist/exports/design-system/components/Badge/README.md +35 -0
  6. package/dist/exports/design-system/components/Badge/preview.html +19 -0
  7. package/dist/exports/design-system/components/Collection/README.md +14 -0
  8. package/dist/exports/design-system/components/CollectionPagination/README.md +15 -0
  9. package/dist/exports/design-system/components/CollectionToolbar/README.md +24 -0
  10. package/dist/exports/design-system/components/DataList/README.md +39 -0
  11. package/dist/exports/design-system/components/DataList/preview.html +475 -0
  12. package/dist/exports/design-system/components/DataTable/README.md +41 -0
  13. package/dist/exports/design-system/components/DataTable/preview.html +475 -0
  14. package/dist/exports/design-system/components/DatePicker/README.md +55 -0
  15. package/dist/exports/design-system/components/DatePicker/preview.html +475 -0
  16. package/dist/exports/design-system/components/EditableList/README.md +33 -0
  17. package/dist/exports/design-system/components/EditableList/preview.html +475 -0
  18. package/dist/exports/design-system/components/EmptyState/README.md +60 -0
  19. package/dist/exports/design-system/components/EmptyState/preview.html +475 -0
  20. package/dist/exports/design-system/components/ListDetail/README.md +43 -0
  21. package/dist/exports/design-system/components/ListDetail/preview.html +475 -0
  22. package/dist/exports/design-system/components/MoneyField/README.md +52 -0
  23. package/dist/exports/design-system/components/MoneyField/preview.html +475 -0
  24. package/dist/exports/design-system/components/Splitter/README.md +42 -0
  25. package/dist/exports/design-system/components/Splitter/preview.html +475 -0
  26. package/dist/exports/design-system/components/Table/README.md +2 -1
  27. package/dist/exports/design-system/components/Table/preview.html +1 -1
  28. package/dist/exports/design-system/components/bundle.css +2377 -190
  29. package/dist/exports/design-system/components/bundle.js +7 -5
  30. package/dist/exports/design-system/components/index.d.ts +3 -21
  31. package/dist/exports/design-system/tokens.json +15 -0
  32. package/dist/exports/figma.json +1 -1
  33. package/dist/exports/mui.js +727 -0
  34. package/dist/exports/tailwind.css +36 -0
  35. package/dist/exports/tokens.dtcg.json +316 -2
  36. package/dist/tokens.css +111 -4
  37. package/dist/tokens.d.ts +93 -0
  38. package/dist/tokens.js +94 -1
  39. package/dist/tokens.json +572 -2
  40. package/package.json +2 -2
@@ -742,6 +742,7 @@
742
742
  --sl-a11y-focus-outline-width: 2px; /** Focus ring thickness. 2px is the WCAG 2.2 minimum that stays visible on every surface. */
743
743
  --sl-a11y-link-focus-outline-offset: 0.25em; /** Links sit inside text, so the offset scales with the font (em) instead of a fixed px. */
744
744
  --sl-a11y-link-focus-ring-radius: 0.125em; /** A slight em-based rounding so inline focus rings hug the text. */
745
+ --sl-a11y-min-target: 24px; /** Smallest target for a fine pointer (WCAG 2.5.8). A mouse can hit 24px; a finger still needs min-touch-target. The splitter handle uses this so the grab area does not cover the scrollbar beside it. */
745
746
  --sl-a11y-min-touch-target: 44px; /** Smallest tap area for any control (WCAG 2.5.5 and Apple HIG both use 44px). */
746
747
  --sl-check-dot-scale: 0.4; /** A radio's dot as a share of the circle, so it scales with the size. */
747
748
  --sl-check-opacity-disabled: 0.5; /** A disabled box fades as a whole; its label turns to disabled text. */
@@ -781,11 +782,17 @@
781
782
  --sl-button-opacity-disabled: 0.5; /** A disabled button fades as a whole, keeping its shape so the layout doesn't jump. */
782
783
  --sl-drawer-popup-size: min(420px, 90vw); /** Width of a side drawer. A bottom or top drawer sizes to its content up to max-size. */
783
784
  --sl-drawer-popup-max-size: 85vh; /** Tallest a bottom or top drawer gets, leaving the page visible above it. */
785
+ --sl-list-detail-split-min-width: 720px; /** Side by side once this element, not the window, is this wide. Dryden used 1100px of the window. A container needs less: a list around 320px and a form around 400px still read at 720px. Narrower, the detail becomes a drawer or a page. */
786
+ --sl-list-detail-detail-default-size: 45%; /** The detail's share when it opens. The list fills the rest, about 55%, which is the split Dryden started from. */
787
+ --sl-list-detail-detail-min-size: 35%; /** The detail cannot be dragged narrower than this, so the form stays readable. */
788
+ --sl-list-detail-detail-max-size: 65%; /** The detail cannot cover more than this, so the list stays usable. Dryden kept the detail between 35% and 65%. */
784
789
  --sl-navigation-menu-popup-min-width: 400px; /** Narrowest a navigation panel gets on wider screens, and the widest a single column of links grows. */
785
790
  --sl-navigation-menu-column-width: 12rem; /** Width of each column in a two-column link list. */
786
791
  --sl-preview-card-popup-min-width: 300px; /** Narrowest a preview card gets, so a short title still has room for its image. */
787
792
  --sl-preview-card-popup-max-width: 450px; /** Widest a preview card gets, so its description keeps a comfortable line length. */
788
793
  --sl-slider-vertical-height: 200px; /** Default length of a vertical slider. */
794
+ --sl-splitter-key-step: 5%; /** One arrow press moves the handle by 5% of the splitter. Dryden used 5%: a nudge you can see, not a jump. */
795
+ --sl-splitter-key-step-large: 10%; /** The Shift step. Twice the arrow step, so a few presses cross the panel without holding the key. */
789
796
  --sl-switch-track-width: 48px; /** Wide enough for the thumb plus the ON/OFF text. */
790
797
  --sl-switch-track-width-sm: 44px;
791
798
  --sl-switch-track-width-lg: 68px;
@@ -1446,6 +1453,11 @@
1446
1453
  --sl-bar-group-gap: var(--sl-space-2); /** Space between groups in a toolbar, wider than inside a group. */
1447
1454
  --sl-bar-separator-length: var(--sl-space-6); /** Divider height, shorter than the controls so the groups still read as one strip. */
1448
1455
  --sl-bar-separator-spacing: var(--sl-space-1); /** Extra space either side of a divider. */
1456
+ --sl-calendar-day-size: var(--sl-space-10); /** A day cell on a pointer. space.10 keeps seven columns inside a phone; touch layouts raise the cell to the minimum touch target in CSS. */
1457
+ --sl-calendar-grid-gap: var(--sl-space-0-5); /** Space between week rows. Days in a week share an edge, so the range band reads as one shape. */
1458
+ --sl-calendar-month-gap: var(--sl-space-4); /** Space between months shown side by side, the same step as panel padding so the two columns line up. */
1459
+ --sl-calendar-header-gap: var(--sl-space-2); /** Space between the month title and the weekday row. */
1460
+ --sl-calendar-panel-padding: var(--sl-space-4); /** Padding inside the popup. The shared popup padding is one step and is too tight for a calendar. */
1449
1461
  --sl-overlay-base: var(--sl-color-black); /** Base color for scrims behind modals. Components apply their own opacity. */
1450
1462
  --sl-disclosure-animation-duration: var(--sl-duration-normal); /** How long a panel takes to open or close, and the chevron to turn. */
1451
1463
  --sl-disclosure-animation-easing: var(--sl-easing-in-out); /** Panels grow and shrink in place, so they ease both ways. */
@@ -1456,6 +1468,22 @@
1456
1468
  --sl-elevation-sm: var(--sl-shadow-sm);
1457
1469
  --sl-elevation-xl: var(--sl-shadow-xl);
1458
1470
  --sl-elevation-xs: var(--sl-shadow-xs);
1471
+ --sl-empty-padding-block-compact: var(--sl-space-6); /** 24px above and below a compact empty state. The same room a popup already gives a plain 'No results' line, so the two stay one height. */
1472
+ --sl-empty-padding-block-standard: var(--sl-space-10); /** 40px. A pane or a section needs more air than a table row, or the block looks stuck to the content around it. */
1473
+ --sl-empty-padding-block-spacious: var(--sl-space-16); /** 64px. A page with nothing else on it. The extra space above keeps the block off the top of the viewport. */
1474
+ --sl-empty-padding-inline-compact: var(--sl-space-4); /** 16px. Enough that a compact row doesn't touch the cell or popup edge. */
1475
+ --sl-empty-padding-inline-standard: var(--sl-space-6); /** 24px. A pane can be wide; the inline padding keeps the block off the sides before the description's own cap does. */
1476
+ --sl-empty-padding-inline-spacious: var(--sl-space-8); /** 32px. A full page, a step wider than a pane. */
1477
+ --sl-empty-gap-compact: var(--sl-space-3); /** 12px between the icon, the text and the actions in a table row or a popup. Tight, because the row is short. */
1478
+ --sl-empty-gap-standard: var(--sl-space-4); /** 16px. The stack in a pane: media, then words, then actions. */
1479
+ --sl-empty-gap-spacious: var(--sl-space-6); /** 24px. A page-sized stack needs the steps to separate, or the circle sits on the title. */
1480
+ --sl-empty-text-gap-compact: var(--sl-space-1); /** 4px between the title and the description in a compact row. They read as one message. */
1481
+ --sl-empty-text-gap-standard: var(--sl-space-1); /** 4px. Same as compact: the description belongs to the title, so it stays close. */
1482
+ --sl-empty-text-gap-spacious: var(--sl-space-2); /** 8px. The page title is larger, so the description steps down a little further. */
1483
+ --sl-empty-media-size-standard: var(--sl-space-12); /** 48px circle around a magnify icon (20px). The icon needs a field, or it reads as a bullet. */
1484
+ --sl-empty-media-size-spacious: var(--sl-space-16); /** 64px circle around a maximize icon (24px). A page can carry a larger mark. Compact has no circle: the icon is icon-size.condense on its own. */
1485
+ --sl-empty-description-max-width: var(--sl-measure-narrow); /** 45ch. A description is one sentence. Past a caption's measure it stretches across a wide pane and stops being a sentence. */
1486
+ --sl-empty-actions-gap: var(--sl-space-2); /** 8px between actions, the same gap a control uses between its icon and its label. The first action is the main one; the rest sit beside it. */
1459
1487
  --sl-field-gap: var(--sl-space-1-5); /** Between a field's label, control and messages. */
1460
1488
  --sl-field-label-spacing: var(--sl-space-1); /** Extra room under the label, so it reads as belonging to the control below it. */
1461
1489
  --sl-field-message-spacing: var(--sl-space-1); /** Extra room above a description or error, so it reads as a note on the control. */
@@ -1498,7 +1526,6 @@
1498
1526
  --sl-popup-separator-spacing: var(--sl-space-1); /** Space above and below a separator. */
1499
1527
  --sl-popup-group-label-padding-top: var(--sl-space-2); /** Space above a group label, so it sits closer to its own rows than to the group before. */
1500
1528
  --sl-popup-group-label-padding-bottom: var(--sl-space-1); /** Space between a group label and its first row. */
1501
- --sl-popup-empty-padding-block: var(--sl-space-6); /** Room around a 'No results' message, so an empty list doesn't collapse to a sliver. */
1502
1529
  --sl-control-height-lg: var(--sl-space-13);
1503
1530
  --sl-control-height-md: var(--sl-space-11);
1504
1531
  --sl-control-height-sm: var(--sl-space-9);
@@ -1809,11 +1836,35 @@
1809
1836
  --sl-avatar-initials-font-size-md: var(--sl-font-size-md); /** Sized to the avatar, not a text style: initials have to fit inside the circle at each size. The rest of the type is title-base. */
1810
1837
  --sl-avatar-initials-font-size-lg: var(--sl-font-size-lg); /** Sized to the avatar, not a text style: initials have to fit inside the circle at each size. The rest of the type is title-base. */
1811
1838
  --sl-avatar-initials-font-size-xl: var(--sl-font-size-2xl); /** Sized to the avatar, not a text style: initials have to fit inside the circle at each size. The rest of the type is title-base. */
1839
+ --sl-badge-height-minimize: var(--sl-space-5); /** 20px. The smallest pill that still holds trigger-minimize. */
1840
+ --sl-badge-height-condense: var(--sl-space-6); /** 24px, the default. Sits in a line of text and in dense rows. */
1841
+ --sl-badge-height-base: var(--sl-space-7); /** 28px, the small control height, for a badge beside base text. */
1842
+ --sl-badge-padding-inline-minimize: var(--sl-space-1); /** 4px. Tighter than a control so a short label stays a pill, not a button. */
1843
+ --sl-badge-padding-inline-condense: var(--sl-space-1-5); /** 6px, the default. */
1844
+ --sl-badge-padding-inline-base: var(--sl-space-2); /** 8px, still inside the small control's inline padding. */
1845
+ --sl-badge-gap-minimize: var(--sl-space-1); /** 4px between a dot or icon and the label at the smallest size. */
1846
+ --sl-badge-gap-condense: var(--sl-space-1); /** 4px, the default. The same gap as the smallest control. */
1847
+ --sl-badge-gap-base: var(--sl-space-1-5); /** 6px, a step wider once the label is base-sized. */
1848
+ --sl-badge-dot-minimize: var(--sl-space-1-5); /** 6px status dot. Smaller than icon-size-minimize so it reads as a mark, not an icon. */
1849
+ --sl-badge-dot-condense: var(--sl-space-2); /** 8px, the default. */
1850
+ --sl-badge-dot-base: var(--sl-space-2); /** 8px. The base badge is taller, but the dot stays a mark. */
1851
+ --sl-collection-tree-indent: var(--sl-space-4); /** How far each deeper level steps in, so a child sits under its parent's text. */
1852
+ --sl-collection-list-row-padding-block: var(--sl-space-3); /** Vertical padding of a list row. The row is not a fixed height, because a second line and an extra slot have to fit. */
1853
+ --sl-collection-list-row-gap: var(--sl-space-2); /** Between the checkbox, the text, the amount and the actions in a list row. */
1854
+ --sl-collection-toolbar-gap: var(--sl-space-2); /** Between the search, the filters and the actions. */
1855
+ --sl-collection-narrow-width: var(--sl-space-96); /** Below this, a table with narrow="list" becomes a list, and the toolbar's search takes the full width. A 360px pane is under it. */
1856
+ --sl-collection-editable-list-stack-width: var(--sl-space-80); /** Below this, editable rows stack and show their own labels. 320px matches. */
1857
+ --sl-collection-selection-column-width: var(--sl-space-10); /** The checkbox column. Wide enough for the control, no wider, so the data keeps the room. */
1812
1858
  --sl-drawer-handle-width: var(--sl-space-10); /** Grab bar length. */
1813
1859
  --sl-drawer-handle-height: var(--sl-space-1); /** Grab bar thickness. */
1860
+ --sl-list-detail-header-gap: var(--sl-space-3); /** Space between the title, the actions and Close. */
1861
+ --sl-list-detail-header-padding: var(--sl-space-4); /** Padding inside the detail header. One step under a dialog, because this is a pane, not a modal. */
1862
+ --sl-money-field-picker-min-inline-size: var(--sl-space-56); /** The currency list shows a code, a name and a symbol, so the popup is wider than the code trigger inside the field. */
1814
1863
  --sl-popover-text-max-width: var(--sl-measure-narrow); /** Keeps the title and description to a readable line length. The popup itself has no fixed cap, so wider content such as a calendar or a form fits; it stops at the space Base UI reports beside the trigger. */
1815
1864
  --sl-popover-popup-min-width: var(--sl-popup-min-width); /** Narrow enough for a short note, wide enough that a title doesn't wrap word by word. */
1816
1865
  --sl-slider-thumb-size: var(--sl-space-5); /** Knob diameter, big enough to grab with a finger on a 4px track. */
1866
+ --sl-splitter-handle-hit-size: var(--sl-a11y-min-touch-target); /** The part a finger grabs. The line stays one stroke. A fine pointer uses a11y.min-target (24px) instead, so the grab area does not cover the panel's scrollbar. Coarse pointers keep this 44px. */
1867
+ --sl-splitter-grip-size: var(--sl-space-1); /** 4px. The diameter of one grip dot. Small enough to sit on the hairline without becoming a second control. */
1817
1868
  --sl-switch-track-text-font-size: var(--sl-font-size-xs); /** Sized to the track, not a text style: the ON/OFF label has to fit inside the switch at each size. The rest of the label uses condense-subtitle-label. */
1818
1869
  --sl-switch-track-text-font-size-sm: var(--sl-font-size-xxs); /** Sized to the track, not a text style: the ON/OFF label has to fit inside the switch at each size. The rest of the label uses condense-subtitle-label. */
1819
1870
  --sl-switch-track-text-font-size-lg: var(--sl-font-size-sm); /** Sized to the track, not a text style: the ON/OFF label has to fit inside the switch at each size. The rest of the label uses condense-subtitle-label. */
@@ -1847,6 +1898,7 @@
1847
1898
  --sl-a11y-focus-ring-radius: var(--sl-radius-focus); /** Rounds the focus ring to match the small control radius. */
1848
1899
  --sl-bar-border-width: var(--sl-stroke-default); /** Strip edge thickness. */
1849
1900
  --sl-bar-radius: var(--sl-radius-surface); /** Strip corners. Controls inside a toggle group take radius.item, so the inner corners follow the outer ones. */
1901
+ --sl-calendar-day-radius: var(--sl-radius-pill); /** Selected days are circles. The pill radius is the same full radius badges and switches use. */
1850
1902
  --sl-check-border-width: var(--sl-stroke-default); /** Edge thickness. */
1851
1903
  --sl-check-radius: var(--sl-radius-box); /** Checkbox corners. Radios are always round. */
1852
1904
  --sl-check-transition: var(--sl-transition-input); /** Changes at the same speed as a field. */
@@ -1879,6 +1931,7 @@
1879
1931
  --sl-popup-radius: var(--sl-radius-surface); /** Corners of a free-floating popup. */
1880
1932
  --sl-popup-radius-field: var(--sl-radius-control); /** Corners of a list that drops from a field, matching the field so the two read as one control. */
1881
1933
  --sl-popup-shadow: var(--sl-elevation-lg); /** Lifts the popup above the page. */
1934
+ --sl-popup-empty-padding-block: var(--sl-empty-padding-block-compact); /** Room around a plain 'No results' line. The same padding as a compact empty state, so a sentence and an EmptyState in that slot take the same space. An EmptyState drops this padding and uses its own. */
1882
1935
  --sl-table-row-height: var(--sl-control-height-sm); /** Row height: the small control height, so a checkbox, input or button in a cell fits without growing the row. */
1883
1936
  --sl-table-header-height: var(--sl-control-height-md); /** Header row height: the regular control height, a little taller than rows so the header reads as its own band. */
1884
1937
  --sl-table-cell-padding-inline: var(--sl-control-padding-inline-sm); /** Space either side of cell text, matching small controls. */
@@ -2062,7 +2115,13 @@
2062
2115
  --sl-status-level-error-quiet-border: var(--sl-scope-error-border); /** quiet in error: outline in error */
2063
2116
  --sl-status-level-error-quiet-border-hover: var(--sl-scope-error-solid-hover); /** quiet in error: outline in error */
2064
2117
  --sl-button-radius: var(--sl-radius-pill); /** Buttons are pills, so they read as actions and never as fields or cards. */
2118
+ --sl-collection-row-height-sm: var(--sl-control-height-sm); /** The dense row, the same height the plain table already uses, so a checkbox fits. */
2119
+ --sl-collection-row-height-md: var(--sl-control-height-md); /** A roomier row when the collection is the page rather than a dense register. */
2120
+ --sl-collection-header-height-sm: var(--sl-control-height-md); /** The dense header, a step above the dense row, matching today's table header. */
2121
+ --sl-collection-header-height-md: var(--sl-control-height-lg); /** The header for the roomier row. */
2122
+ --sl-splitter-handle-size: var(--sl-stroke-default); /** The visible separator. One stroke, the same hairline as Separator, so a splitter reads as a divider you can grab. */
2065
2123
  --sl-focus-shadow-3px-error: 0 0 0 3px var(--sl-status-error); /** Focus halo for a field with an error. */
2124
+ --sl-calendar-day-color: var(--sl-text-primary); /** A day in the month being shown. */
2066
2125
  --sl-border-accent: var(--sl-scope-accent-border); /** Borders that signal selection or the active item. */
2067
2126
  --sl-border-default: var(--sl-scope-chrome-divider); /** Everyday dividers and control outlines. Darkens under prefers-contrast: more. */
2068
2127
  --sl-border-strong: var(--sl-scope-chrome-border-strong); /** Borders that identify a control, such as inputs and unchecked checkboxes. 3:1 against the canvas, as WCAG asks for control boundaries. */
@@ -2162,6 +2221,12 @@
2162
2221
  --sl-bar-background: var(--sl-surface-tray); /** Strip fill. */
2163
2222
  --sl-bar-border-color: var(--sl-border-default); /** Strip edge. */
2164
2223
  --sl-bar-separator-color: var(--sl-border-default); /** Divider between groups. */
2224
+ --sl-calendar-day-color-outside: var(--sl-text-tertiary); /** A day from the previous or next month, still selectable, drawn back so it does not compete with this month. */
2225
+ --sl-calendar-day-color-disabled: var(--sl-text-disabled); /** A day outside the allowed period, or one a length rule rejects. It stays in the tab order so the reason can be read. */
2226
+ --sl-calendar-range-background: var(--sl-interactive-tint-active); /** The band between the start and end of a period. Same tint as a selected list item, quieter than the start and end circles. */
2227
+ --sl-calendar-range-color: var(--sl-text-on-tint-strong); /** Day numbers that sit on the range band. The on-tint text color is the one that stays readable on interactive.tint-active. */
2228
+ --sl-calendar-today-ring: var(--sl-border-accent); /** An inset ring on today, including when today is also selected, so today is never only a color of the number. */
2229
+ --sl-calendar-weekday-color: var(--sl-text-tertiary); /** Weekday initials and week numbers are labels, not choices. */
2165
2230
  --sl-check-border-color: var(--sl-border-control); /** Empty box edge. Passes 3:1 so the box can be found before it's ticked. */
2166
2231
  --sl-check-border-color-hover: var(--sl-border-control-hover); /** Edge under the pointer. */
2167
2232
  --sl-check-background-checked: var(--sl-interactive-default); /** Ticked box fill, the brand's interactive color. */
@@ -2204,6 +2269,7 @@
2204
2269
  --sl-field-color-disabled: var(--sl-text-disabled); /** The value in a disabled field. */
2205
2270
  --sl-field-placeholder-color: var(--sl-text-tertiary); /** Hint text before anything is typed. */
2206
2271
  --sl-field-shadow-focus-error: var(--sl-focus-shadow-3px-error); /** Halo while typing in an invalid field. */
2272
+ --sl-field-affix-color: var(--sl-text-secondary); /** A prefix or suffix drawn inside the field (a currency symbol, a unit). Muted so it reads as part of the control, not as the value. */
2207
2273
  --sl-gauge-track-color: var(--sl-fill-track); /** The empty part of the bar. Every palette's fill reads 3:1 on it, so the amount is clear in both themes. */
2208
2274
  --sl-gauge-value-color: var(--sl-text-secondary); /** The number, quieter than its label. */
2209
2275
  --sl-icon-button-color: var(--sl-text-tertiary); /** Quiet at rest so it doesn't compete with the content. */
@@ -2226,12 +2292,15 @@
2226
2292
  --sl-table-header-background-hover: var(--sl-fill-subtle); /** A header cell under the pointer, showing it can be clicked to sort. */
2227
2293
  --sl-table-border-color: var(--sl-border-default); /** The grid's outer edge and the line under the header. */
2228
2294
  --sl-table-row-border-color: var(--sl-border-subtle); /** Hairlines between rows, quiet so the data leads. */
2295
+ --sl-table-row-current: var(--sl-surface-tray); /** The open row beside a detail pane. The tray, a step off the page, so secondary text on it still passes AA in dark. A selected row keeps its own tint, so a checked row and the row you are reading can both show. */
2296
+ --sl-table-group-header-background: var(--sl-surface-tray); /** A group header. The tray, like the column header, so a group reads as chrome rather than another data row. */
2229
2297
  --sl-table-column-hover: var(--sl-fill-subtle); /** Column under the pointer, when column hover is on. Neutral so it never reads as a selection. */
2230
2298
  --sl-table-range-background: var(--sl-interactive-tint); /** Cells inside a dragged range selection. */
2231
2299
  --sl-emphasis-bold-fg: var(--sl-scope-accent-on-solid); /** bold in default: solid in accent (primary) */
2232
2300
  --sl-status-level-default-bold-fg: var(--sl-scope-accent-on-solid); /** bold in default: solid in accent (primary) */
2233
2301
  --sl-drawer-handle-color: var(--sl-border-strong); /** The grab bar on bottom drawers. Strong border so it reads as something to drag. */
2234
2302
  --sl-shadow-outline: 0 0 0 3px color-mix(in oklab, var(--sl-focus-ring) 60%, transparent); /** Focus halo for controls that use box-shadow instead of outline: the focus ring color at 60% opacity, so it follows the accent and the theme. Becomes currentColor under prefers-contrast: more. */
2303
+ --sl-calendar-day-background-hover: var(--sl-item-background-hover); /** The same hover tint as a list item, so a day feels like a choice in a list. */
2235
2304
  --sl-check-mark-color: var(--sl-text-on-primary); /** Check mark, dash or dot on a ticked fill. */
2236
2305
  --sl-text-on-accent: var(--sl-text-on-primary); /** Alias for text placed on any accent fill. */
2237
2306
  --sl-content-kbd-text: var(--sl-text-on-inverse); /** Text on keycaps. */
@@ -5478,7 +5547,8 @@
5478
5547
  [data-emphasis='bold'],
5479
5548
  .Button[data-variant='solid']:not([data-emphasis]),
5480
5549
  .Button:not([data-variant]):not([data-emphasis]),
5481
- .AvatarRoot:not([data-emphasis]) {
5550
+ .AvatarRoot:not([data-emphasis]),
5551
+ .CalendarDay[data-selected]:not([data-emphasis]) {
5482
5552
  --sl-e-bg: var(--sl-scope-solid);
5483
5553
  --sl-e-bg-hover: var(--sl-scope-solid-hover);
5484
5554
  --sl-e-bg-active: var(--sl-scope-solid-active);
@@ -5498,7 +5568,9 @@
5498
5568
  --sl-e-border-hover: var(--sl-scope-solid-hover);
5499
5569
  }
5500
5570
 
5501
- [data-emphasis='subtle'] {
5571
+ [data-emphasis='subtle'],
5572
+ .Badge:not([data-emphasis]),
5573
+ .EmptyStateMedia:not([data-emphasis]) {
5502
5574
  --sl-e-bg: var(--sl-scope-soft);
5503
5575
  --sl-e-bg-hover: var(--sl-scope-soft-hover);
5504
5576
  --sl-e-bg-active: var(--sl-scope-soft-active);
@@ -5507,7 +5579,9 @@
5507
5579
  --sl-e-border-hover: var(--sl-scope-soft-hover);
5508
5580
  }
5509
5581
 
5510
- [data-emphasis='subtle']:not([data-color], [data-status], [data-status] *, .Toast[data-type], .Toast[data-type] *) {
5582
+ [data-emphasis='subtle']:not([data-color], [data-status], [data-status] *, .Toast[data-type], .Toast[data-type] *),
5583
+ .Badge:not([data-emphasis]):not([data-color], [data-status], [data-status] *, .Toast[data-type], .Toast[data-type] *),
5584
+ .EmptyStateMedia:not([data-emphasis]):not([data-color], [data-color] *, [data-status], [data-status] *, .Toast[data-type], .Toast[data-type] *) {
5511
5585
  --sl-scope-solid: var(--sl-scope-chrome-solid);
5512
5586
  --sl-scope-solid-hover: var(--sl-scope-chrome-solid-hover);
5513
5587
  --sl-scope-solid-active: var(--sl-scope-chrome-solid-active);
@@ -5646,6 +5720,13 @@
5646
5720
  --sl-bar-background: var(--sl-surface-tray);
5647
5721
  --sl-bar-border-color: var(--sl-border-default);
5648
5722
  --sl-bar-separator-color: var(--sl-border-default);
5723
+ --sl-calendar-day-color: var(--sl-text-primary);
5724
+ --sl-calendar-day-color-outside: var(--sl-text-tertiary);
5725
+ --sl-calendar-day-color-disabled: var(--sl-text-disabled);
5726
+ --sl-calendar-range-background: var(--sl-interactive-tint-active);
5727
+ --sl-calendar-range-color: var(--sl-text-on-tint-strong);
5728
+ --sl-calendar-today-ring: var(--sl-border-accent);
5729
+ --sl-calendar-weekday-color: var(--sl-text-tertiary);
5649
5730
  --sl-check-border-color: var(--sl-border-control);
5650
5731
  --sl-check-border-color-hover: var(--sl-border-control-hover);
5651
5732
  --sl-check-background-checked: var(--sl-interactive-default);
@@ -5674,6 +5755,7 @@
5674
5755
  --sl-field-color-disabled: var(--sl-text-disabled);
5675
5756
  --sl-field-placeholder-color: var(--sl-text-tertiary);
5676
5757
  --sl-field-shadow-focus: var(--sl-focus-shadow-3px-primary);
5758
+ --sl-field-affix-color: var(--sl-text-secondary);
5677
5759
  --sl-gauge-track-color: var(--sl-fill-track);
5678
5760
  --sl-gauge-label-color: var(--sl-text-primary);
5679
5761
  --sl-gauge-value-color: var(--sl-text-secondary);
@@ -5707,10 +5789,13 @@
5707
5789
  --sl-table-row-border-color: var(--sl-border-subtle);
5708
5790
  --sl-table-row-hover: var(--sl-item-background-hover);
5709
5791
  --sl-table-row-selected: var(--sl-item-background-selected);
5792
+ --sl-table-row-current: var(--sl-surface-tray);
5793
+ --sl-table-group-header-background: var(--sl-surface-tray);
5710
5794
  --sl-table-column-hover: var(--sl-fill-subtle);
5711
5795
  --sl-table-range-background: var(--sl-interactive-tint);
5712
5796
  --sl-table-range-border: var(--sl-focus-ring);
5713
5797
  --sl-drawer-handle-color: var(--sl-border-strong);
5798
+ --sl-calendar-day-background-hover: var(--sl-item-background-hover);
5714
5799
  --sl-check-background: var(--sl-field-background);
5715
5800
  }
5716
5801
 
@@ -5781,6 +5866,13 @@
5781
5866
  --sl-bar-background: var(--sl-surface-tray);
5782
5867
  --sl-bar-border-color: var(--sl-border-default);
5783
5868
  --sl-bar-separator-color: var(--sl-border-default);
5869
+ --sl-calendar-day-color: var(--sl-text-primary);
5870
+ --sl-calendar-day-color-outside: var(--sl-text-tertiary);
5871
+ --sl-calendar-day-color-disabled: var(--sl-text-disabled);
5872
+ --sl-calendar-range-background: var(--sl-interactive-tint-active);
5873
+ --sl-calendar-range-color: var(--sl-text-on-tint-strong);
5874
+ --sl-calendar-today-ring: var(--sl-border-accent);
5875
+ --sl-calendar-weekday-color: var(--sl-text-tertiary);
5784
5876
  --sl-check-border-color: var(--sl-border-control);
5785
5877
  --sl-check-border-color-hover: var(--sl-border-control-hover);
5786
5878
  --sl-check-background-checked: var(--sl-interactive-default);
@@ -5809,6 +5901,7 @@
5809
5901
  --sl-field-color-disabled: var(--sl-text-disabled);
5810
5902
  --sl-field-placeholder-color: var(--sl-text-tertiary);
5811
5903
  --sl-field-shadow-focus: var(--sl-focus-shadow-3px-primary);
5904
+ --sl-field-affix-color: var(--sl-text-secondary);
5812
5905
  --sl-gauge-track-color: var(--sl-fill-track);
5813
5906
  --sl-gauge-label-color: var(--sl-text-primary);
5814
5907
  --sl-gauge-value-color: var(--sl-text-secondary);
@@ -5842,10 +5935,13 @@
5842
5935
  --sl-table-row-border-color: var(--sl-border-subtle);
5843
5936
  --sl-table-row-hover: var(--sl-item-background-hover);
5844
5937
  --sl-table-row-selected: var(--sl-item-background-selected);
5938
+ --sl-table-row-current: var(--sl-surface-tray);
5939
+ --sl-table-group-header-background: var(--sl-surface-tray);
5845
5940
  --sl-table-column-hover: var(--sl-fill-subtle);
5846
5941
  --sl-table-range-background: var(--sl-interactive-tint);
5847
5942
  --sl-table-range-border: var(--sl-focus-ring);
5848
5943
  --sl-drawer-handle-color: var(--sl-border-strong);
5944
+ --sl-calendar-day-background-hover: var(--sl-item-background-hover);
5849
5945
  --sl-check-background: var(--sl-field-background);
5850
5946
  }
5851
5947
 
@@ -5916,6 +6012,13 @@
5916
6012
  --sl-bar-background: var(--sl-surface-tray);
5917
6013
  --sl-bar-border-color: var(--sl-border-default);
5918
6014
  --sl-bar-separator-color: var(--sl-border-default);
6015
+ --sl-calendar-day-color: var(--sl-text-primary);
6016
+ --sl-calendar-day-color-outside: var(--sl-text-tertiary);
6017
+ --sl-calendar-day-color-disabled: var(--sl-text-disabled);
6018
+ --sl-calendar-range-background: var(--sl-interactive-tint-active);
6019
+ --sl-calendar-range-color: var(--sl-text-on-tint-strong);
6020
+ --sl-calendar-today-ring: var(--sl-border-accent);
6021
+ --sl-calendar-weekday-color: var(--sl-text-tertiary);
5919
6022
  --sl-check-border-color: var(--sl-border-control);
5920
6023
  --sl-check-border-color-hover: var(--sl-border-control-hover);
5921
6024
  --sl-check-background-checked: var(--sl-interactive-default);
@@ -5944,6 +6047,7 @@
5944
6047
  --sl-field-color-disabled: var(--sl-text-disabled);
5945
6048
  --sl-field-placeholder-color: var(--sl-text-tertiary);
5946
6049
  --sl-field-shadow-focus: var(--sl-focus-shadow-3px-primary);
6050
+ --sl-field-affix-color: var(--sl-text-secondary);
5947
6051
  --sl-gauge-track-color: var(--sl-fill-track);
5948
6052
  --sl-gauge-label-color: var(--sl-text-primary);
5949
6053
  --sl-gauge-value-color: var(--sl-text-secondary);
@@ -5977,10 +6081,13 @@
5977
6081
  --sl-table-row-border-color: var(--sl-border-subtle);
5978
6082
  --sl-table-row-hover: var(--sl-item-background-hover);
5979
6083
  --sl-table-row-selected: var(--sl-item-background-selected);
6084
+ --sl-table-row-current: var(--sl-surface-tray);
6085
+ --sl-table-group-header-background: var(--sl-surface-tray);
5980
6086
  --sl-table-column-hover: var(--sl-fill-subtle);
5981
6087
  --sl-table-range-background: var(--sl-interactive-tint);
5982
6088
  --sl-table-range-border: var(--sl-focus-ring);
5983
6089
  --sl-drawer-handle-color: var(--sl-border-strong);
6090
+ --sl-calendar-day-background-hover: var(--sl-item-background-hover);
5984
6091
  --sl-check-background: var(--sl-field-background);
5985
6092
  }
5986
6093
  }
@@ -6306,7 +6413,7 @@
6306
6413
  }
6307
6414
 
6308
6415
 
6309
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
6416
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6310
6417
  /* Loomiere for Base UI: component styles. Brand-free: every value is a --sl- variable from a
6311
6418
  Loomiere theme. Load the theme first:
6312
6419
  @import '<your theme>/tokens.css';
@@ -6316,7 +6423,7 @@
6316
6423
  /* Document defaults, in the reset layer so any unlayered rule wins over them, and so layered
6317
6424
  frameworks (Chakra's recipes, Tailwind's utilities) are not undone by them. */
6318
6425
  @layer reset {
6319
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
6426
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6320
6427
  /* CSS Reset - Mojave Theme */
6321
6428
 
6322
6429
  /* ============================================
@@ -6760,7 +6867,7 @@ hr {
6760
6867
  }
6761
6868
  }
6762
6869
  @layer reset {
6763
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
6870
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6764
6871
  /* Accessibility — base rules (no theme color dependencies). Theme-specific focus/invalid: accessibility-theme.css */
6765
6872
 
6766
6873
  /* Remove default focus; keyboard focus styled in accessibility-theme.css */
@@ -6873,7 +6980,7 @@ main:focus {
6873
6980
 
6874
6981
  }
6875
6982
  @layer reset {
6876
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
6983
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6877
6984
  /* Focus, invalid, contrast — requires theme tokens (after theme-accessibility.css). */
6878
6985
 
6879
6986
  :focus-visible {
@@ -6941,7 +7048,7 @@ button,
6941
7048
 
6942
7049
  }
6943
7050
  /* Component styles */
6944
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7051
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6945
7052
  /* Accordion - Mojave Theme
6946
7053
  *
6947
7054
  * No component tokens. Hover, press, chevron, divider and motion are the disclosure
@@ -7062,7 +7169,7 @@ button,
7062
7169
  overflow: hidden;
7063
7170
  }
7064
7171
 
7065
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7172
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7066
7173
  /* Alert Dialog - Mojave Theme
7067
7174
  *
7068
7175
  * No component tokens and no rules of its own. An alert dialog looks exactly like a
@@ -7071,7 +7178,7 @@ button,
7071
7178
  * cancel quiet, and a destructive one bold with data-color="error".
7072
7179
  */
7073
7180
 
7074
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7181
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7075
7182
  /* Autocomplete - Mojave Theme
7076
7183
  *
7077
7184
  * No component tokens. The input is Input (Input.css), the clear button is an icon
@@ -7273,7 +7380,7 @@ button,
7273
7380
  (reset-accessibility.css).
7274
7381
  ============================================ */
7275
7382
 
7276
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7383
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7277
7384
  /* Avatar - Mojave Theme
7278
7385
  *
7279
7386
  * A round picture with a ring in the page color, so avatars in a group cut out of each other in
@@ -7381,7 +7488,7 @@ button,
7381
7488
  }
7382
7489
  }
7383
7490
 
7384
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7491
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7385
7492
  /* Button - Mojave Theme
7386
7493
  *
7387
7494
  * Colors are the brand's emphasis levels, sizes are control.*, text is the trigger
@@ -7531,7 +7638,7 @@ button,
7531
7638
  font-size: var(--sl-icon-size-maximize);
7532
7639
  }
7533
7640
 
7534
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7641
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7535
7642
  /* Checkbox - Mojave Theme
7536
7643
  * Sizes follow the label: the box is the icon size one tier above the label's text
7537
7644
  * tier (like a button's icon) and the check mark one tier below it.
@@ -7688,7 +7795,7 @@ button,
7688
7795
  border-radius: var(--sl-radius-pill);
7689
7796
  }
7690
7797
 
7691
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7798
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7692
7799
  /* Checkbox Group - Mojave Theme */
7693
7800
 
7694
7801
  /* Each checkbox row is already a full tap target tall, so the rows sit close. */
@@ -7704,7 +7811,7 @@ button,
7704
7811
  pointer-events: none;
7705
7812
  }
7706
7813
 
7707
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7814
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7708
7815
  /* Collapsible - Mojave Theme
7709
7816
  *
7710
7817
  * No component tokens. Hover, press, chevron and motion are the disclosure concept
@@ -7820,7 +7927,7 @@ button,
7820
7927
  background: var(--sl-surface-raised);
7821
7928
  }
7822
7929
 
7823
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
7930
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7824
7931
  /* Combobox - Mojave Theme
7825
7932
  *
7826
7933
  * No component tokens. The input is Input (Input.css); the chips box is a field; the
@@ -8305,7 +8412,7 @@ button,
8305
8412
  color: var(--sl-text-tertiary);
8306
8413
  }
8307
8414
 
8308
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8415
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8309
8416
  /* Context Menu - Mojave Theme
8310
8417
  *
8311
8418
  * No component tokens. Opens on right-click; the trigger area only sets the cursor. The popup is the popup concept, rows are item rows at the
@@ -8474,7 +8581,7 @@ button,
8474
8581
  stroke-width: var(--sl-stroke-default);
8475
8582
  }
8476
8583
 
8477
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8584
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8478
8585
  /* Dialog and Alert dialog - Mojave Theme
8479
8586
  *
8480
8587
  * Both are centered modals built from the modal concept (tokens/semantic/modal.json):
@@ -8620,7 +8727,7 @@ button,
8620
8727
  margin-top: var(--sl-modal-actions-spacing);
8621
8728
  }
8622
8729
 
8623
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8730
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8624
8731
  /* Drawer - a panel that slides in from an edge and can be swiped away.
8625
8732
  The surface, scrim, heading and motion are the modal concept's (--sl-modal-*), so a
8626
8733
  drawer reads as a dialog's sibling; only its size and grab bar are its own
@@ -8747,7 +8854,7 @@ button,
8747
8854
  color: var(--sl-modal-description-color);
8748
8855
  }
8749
8856
 
8750
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8857
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8751
8858
  /* Field - Mojave Theme
8752
8859
  *
8753
8860
  * Label, control, description and error. No component tokens: spacing is the field
@@ -8808,7 +8915,7 @@ textarea.FieldControl {
8808
8915
  height: auto;
8809
8916
  }
8810
8917
 
8811
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8918
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8812
8919
  /* Fieldset - Mojave Theme
8813
8920
  *
8814
8921
  * No component tokens: a titled group of fields, spaced by the stack gaps, with
@@ -8850,7 +8957,7 @@ textarea.FieldControl {
8850
8957
  color: var(--sl-text-secondary);
8851
8958
  }
8852
8959
 
8853
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8960
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8854
8961
  /* Form - Mojave Theme
8855
8962
  *
8856
8963
  * No component tokens: fields stack with the large block space, and the action
@@ -8870,7 +8977,7 @@ textarea.FieldControl {
8870
8977
  margin-top: var(--sl-space-block-md);
8871
8978
  }
8872
8979
 
8873
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
8980
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
8874
8981
  /* Input - Mojave Theme
8875
8982
  *
8876
8983
  * No component tokens: the look is the field concept (tokens/semantic/field.json),
@@ -9007,7 +9114,7 @@ textarea.FieldControl {
9007
9114
  padding-inline: var(--sl-control-padding-inline-lg);
9008
9115
  }
9009
9116
 
9010
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
9117
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9011
9118
  /* Menu - Mojave Theme
9012
9119
  *
9013
9120
  * No component tokens. The trigger is a Button. The popup is the popup concept, rows are item rows at the
@@ -9156,7 +9263,7 @@ textarea.FieldControl {
9156
9263
  color: var(--sl-text-tertiary);
9157
9264
  }
9158
9265
 
9159
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
9266
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9160
9267
  /* Menubar - Mojave Theme
9161
9268
  *
9162
9269
  * No component tokens. A row of quiet triggers, each opening a menu. The popup is the popup concept, rows are item rows at the
@@ -9349,7 +9456,7 @@ textarea.FieldControl {
9349
9456
  color: var(--sl-text-tertiary);
9350
9457
  }
9351
9458
 
9352
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
9459
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9353
9460
  /* Meter - Mojave Theme
9354
9461
  *
9355
9462
  * A gauge (tokens/semantic/gauge.json). The fill is the solid color of the scope around it:
@@ -9412,7 +9519,7 @@ textarea.FieldControl {
9412
9519
  height: var(--sl-gauge-height-lg);
9413
9520
  }
9414
9521
 
9415
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
9522
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9416
9523
  /* Navigation Menu - Mojave Theme
9417
9524
  *
9418
9525
  * The strip is the bar concept, the panel is the popup concept and each link is an item
@@ -9832,7 +9939,7 @@ textarea.FieldControl {
9832
9939
  width: 100%;
9833
9940
  }
9834
9941
 
9835
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
9942
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9836
9943
  /* Number Field - Mojave Theme
9837
9944
  *
9838
9945
  * No component tokens. The input is Input (Input.css) and the label, description and
@@ -9923,7 +10030,7 @@ textarea.FieldControl {
9923
10030
  user-select: none;
9924
10031
  }
9925
10032
 
9926
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10033
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9927
10034
  /* OTP Field - Mojave Theme
9928
10035
  *
9929
10036
  * One-time code entry: a row of single-character inputs. Each slot is the same control as Input
@@ -9986,7 +10093,7 @@ textarea.FieldControl {
9986
10093
  letter-spacing: var(--sl-font-body-magnify-letter-spacing);
9987
10094
  }
9988
10095
 
9989
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10096
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
9990
10097
  /* Popover - Mojave Theme */
9991
10098
 
9992
10099
  /* ============================================
@@ -10151,7 +10258,7 @@ textarea.FieldControl {
10151
10258
  fill: var(--sl-popup-arrow-stroke);
10152
10259
  }
10153
10260
 
10154
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10261
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10155
10262
  /* Preview Card - Mojave Theme
10156
10263
  *
10157
10264
  * The popup concept (surface, arrow, motion) with a title-magnify title and condense
@@ -10268,7 +10375,7 @@ textarea.FieldControl {
10268
10375
  fill: var(--sl-popup-arrow-stroke);
10269
10376
  }
10270
10377
 
10271
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10378
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10272
10379
  /* Progress - Mojave Theme
10273
10380
  *
10274
10381
  * A gauge (tokens/semantic/gauge.json), the same bar as Meter. The fill is the solid color of
@@ -10345,7 +10452,7 @@ textarea.FieldControl {
10345
10452
  height: var(--sl-gauge-height-lg);
10346
10453
  }
10347
10454
 
10348
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10455
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10349
10456
  /* Radio - Mojave Theme
10350
10457
  * Same box as Checkbox, always round. Sizes follow the label the same way, and the
10351
10458
  * dot is a share of the circle (check.dot-scale).
@@ -10497,7 +10604,7 @@ textarea.FieldControl {
10497
10604
  gap: var(--sl-gap-stack-sm);
10498
10605
  }
10499
10606
 
10500
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10607
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10501
10608
  /* Scroll Area - Mojave Theme
10502
10609
  *
10503
10610
  * The scrollbar is the content scrollbar (content.scrollbar-*): a track that stays clear until
@@ -10579,7 +10686,7 @@ textarea.FieldControl {
10579
10686
  background: transparent;
10580
10687
  }
10581
10688
 
10582
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10689
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10583
10690
  /* Select - Mojave Theme
10584
10691
  *
10585
10692
  * The trigger is a field (the field pattern, control sizes, the base text style); the
@@ -10864,7 +10971,7 @@ textarea.FieldControl {
10864
10971
  stroke-width: var(--sl-stroke-default);
10865
10972
  }
10866
10973
 
10867
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
10974
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10868
10975
  /* Separator - Mojave Theme
10869
10976
  *
10870
10977
  * A hairline in the everyday divider color (border.default), one stroke thick, with a step of
@@ -10892,7 +10999,7 @@ textarea.FieldControl {
10892
10999
  margin-inline: var(--sl-space-4);
10893
11000
  }
10894
11001
 
10895
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11002
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
10896
11003
  /* Slider - Mojave Theme
10897
11004
  *
10898
11005
  * A slider is a gauge you can drag: the track, fill and label row are gauge.* (the same bar as
@@ -11058,7 +11165,7 @@ textarea.FieldControl {
11058
11165
  transform: translate(-50%, 50%);
11059
11166
  }
11060
11167
 
11061
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11168
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11062
11169
  /* Switch - Mojave Theme
11063
11170
  * Switch keeps its track sizes. The thumb, its travel and the ON/OFF text are
11064
11171
  * worked out from them: the thumb fills the track's height inside the padding,
@@ -11224,152 +11331,7 @@ textarea.FieldControl {
11224
11331
  color: var(--sl-text-disabled);
11225
11332
  }
11226
11333
 
11227
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11228
- /* Table - Mojave Theme
11229
- *
11230
- * Base UI has no table, so this styles the native <table class="Table"> elements with the
11231
- * table concept (tokens/semantic/table.json), the same tokens the AG Grid themes read: a small
11232
- * hand-built table and a full grid look alike. Rows answer to aria-selected="true" (or
11233
- * data-selected) for selection; cells take data-align="end" for numbers.
11234
- */
11235
-
11236
- .Table {
11237
- font-family: var(--sl-font-body-condense-font-family);
11238
- font-size: var(--sl-font-body-condense-font-size);
11239
- font-weight: var(--sl-font-body-condense-font-weight);
11240
- line-height: var(--sl-font-body-condense-line-height);
11241
- letter-spacing: var(--sl-font-body-condense-letter-spacing);
11242
- box-sizing: border-box;
11243
- width: 100%;
11244
- border-collapse: separate;
11245
- border-spacing: 0;
11246
- background: var(--sl-table-background);
11247
- color: var(--sl-table-color);
11248
- border: var(--sl-stroke-default) solid var(--sl-table-border-color);
11249
- border-radius: var(--sl-table-radius);
11250
- overflow: hidden;
11251
- font-variant-numeric: tabular-nums;
11252
- }
11253
-
11254
- .Table caption {
11255
- font-family: var(--sl-font-body-condense-font-family);
11256
- font-size: var(--sl-font-body-condense-font-size);
11257
- font-weight: var(--sl-font-body-condense-font-weight);
11258
- line-height: var(--sl-font-body-condense-line-height);
11259
- letter-spacing: var(--sl-font-body-condense-letter-spacing);
11260
- caption-side: bottom;
11261
- padding-block: var(--sl-space-2);
11262
- color: var(--sl-table-subtle-color);
11263
- text-align: start;
11264
- }
11265
-
11266
- /* Header: the tray band, a little taller than the rows */
11267
- .Table th {
11268
- font-family: var(--sl-font-subtitle-condense-font-family);
11269
- font-size: var(--sl-font-subtitle-condense-font-size);
11270
- font-weight: var(--sl-font-subtitle-condense-font-weight);
11271
- line-height: var(--sl-font-subtitle-condense-line-height);
11272
- letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
11273
- height: var(--sl-table-header-height);
11274
- padding-block: 0;
11275
- padding-inline: var(--sl-table-cell-padding-inline);
11276
- background: var(--sl-table-header-background);
11277
- color: var(--sl-table-header-color);
11278
- text-align: start;
11279
- vertical-align: middle;
11280
- border-bottom: var(--sl-stroke-default) solid var(--sl-table-border-color);
11281
- }
11282
-
11283
- /* A header that sorts: aria-sort on the th */
11284
- .Table th[aria-sort] {
11285
- cursor: pointer;
11286
- transition: background-color var(--sl-duration-fast) var(--sl-easing-default);
11287
- }
11288
-
11289
- .Table th[aria-sort]:hover {
11290
- background: var(--sl-table-header-background-hover);
11291
- }
11292
-
11293
- /* Body cells */
11294
- .Table td {
11295
- height: var(--sl-table-row-height);
11296
- padding-block: 0;
11297
- padding-inline: var(--sl-table-cell-padding-inline);
11298
- vertical-align: middle;
11299
- border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
11300
- }
11301
-
11302
- .Table tbody tr:last-child td,
11303
- .Table tbody:last-child tr:last-child td {
11304
- border-bottom: none;
11305
- }
11306
-
11307
- /* A row header (th in tbody) reads like a cell, in the header's weight */
11308
- .Table tbody th {
11309
- background: transparent;
11310
- border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
11311
- }
11312
-
11313
- /* Numbers and amounts: right-aligned so digits line up */
11314
- .Table [data-align='end'] {
11315
- text-align: end;
11316
- }
11317
-
11318
- .Table [data-align='center'] {
11319
- text-align: center;
11320
- }
11321
-
11322
- /* Secondary text in a cell */
11323
- .Table [data-subtle] {
11324
- color: var(--sl-table-subtle-color);
11325
- }
11326
-
11327
- /* Hover and selection: the same tints as list items */
11328
- @media (hover: hover) {
11329
- .Table tbody tr:hover > * {
11330
- background: var(--sl-table-row-hover);
11331
- color: var(--sl-item-color-hover);
11332
- }
11333
- }
11334
-
11335
- .Table tbody tr:is([aria-selected='true'], [data-selected]) > * {
11336
- background: var(--sl-table-row-selected);
11337
- color: var(--sl-item-color-selected);
11338
- }
11339
-
11340
- /* Footer: totals on the tray band */
11341
- .Table tfoot td {
11342
- font-family: var(--sl-font-subtitle-condense-font-family);
11343
- font-size: var(--sl-font-subtitle-condense-font-size);
11344
- font-weight: var(--sl-font-subtitle-condense-font-weight);
11345
- line-height: var(--sl-font-subtitle-condense-line-height);
11346
- letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
11347
- background: var(--sl-table-header-background);
11348
- border-top: var(--sl-stroke-default) solid var(--sl-table-border-color);
11349
- border-bottom: none;
11350
- }
11351
-
11352
- /* A header that stays put while the body scrolls (the table's wrapper scrolls) */
11353
- .Table[data-sticky-header] thead th {
11354
- position: sticky;
11355
- top: 0;
11356
- z-index: var(--sl-z-index-docked);
11357
- }
11358
-
11359
- /* Empty state: one cell spanning the columns */
11360
- .Table td[data-empty] {
11361
- height: auto;
11362
- padding-block: var(--sl-space-10);
11363
- color: var(--sl-text-tertiary);
11364
- text-align: center;
11365
- }
11366
-
11367
- .Table tbody tr:has(> td[data-empty]):hover > * {
11368
- background: transparent;
11369
- color: var(--sl-text-tertiary);
11370
- }
11371
-
11372
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11334
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11373
11335
  /* Tabs - Mojave Theme
11374
11336
  *
11375
11337
  * No component tokens. The divider, the selected line and color, hover and the disabled
@@ -11505,7 +11467,7 @@ textarea.FieldControl {
11505
11467
  padding: var(--sl-space-6);
11506
11468
  }
11507
11469
 
11508
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11470
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11509
11471
  /* Toast - Mojave Theme
11510
11472
  *
11511
11473
  * A toast is a notice (tokens/semantic/notice.json) on the popup surface. A toast whose type
@@ -11741,7 +11703,7 @@ textarea.FieldControl {
11741
11703
  flex-shrink: 0;
11742
11704
  }
11743
11705
 
11744
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11706
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11745
11707
  /* Toggle - Mojave Theme
11746
11708
  * A toggle is a button that stays pressed: the same heights, padding, gap and
11747
11709
  * trigger text style as a button of the same size. Pressed, it takes its emphasis level's
@@ -11853,7 +11815,7 @@ textarea.FieldControl {
11853
11815
  height: var(--sl-icon-size-maximize);
11854
11816
  }
11855
11817
 
11856
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11818
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11857
11819
  /* Toggle Group - Mojave Theme
11858
11820
  *
11859
11821
  * No component tokens. The strip is the bar concept (tokens/semantic/bar.json); the
@@ -11874,7 +11836,7 @@ textarea.FieldControl {
11874
11836
  border-radius: var(--sl-radius-item);
11875
11837
  }
11876
11838
 
11877
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11839
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11878
11840
  /* Toolbar - Mojave Theme
11879
11841
  *
11880
11842
  * The strip is the bar concept (tokens/semantic/bar.json). Buttons, toggles, selects
@@ -11936,7 +11898,7 @@ textarea.FieldControl {
11936
11898
  max-width: var(--sl-toolbar-input-max-width);
11937
11899
  }
11938
11900
 
11939
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
11901
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11940
11902
  /* Tooltip - Mojave Theme
11941
11903
  *
11942
11904
  * The inverse surface (surface.inverse, text.on-inverse-surface) with condense text, so a tooltip
@@ -11995,3 +11957,2228 @@ textarea.FieldControl {
11995
11957
  transform: none;
11996
11958
  }
11997
11959
  }
11960
+
11961
+ /* Custom components: not Base UI parts. Built from existing concepts and tokens. */
11962
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
11963
+ /* Badge
11964
+ *
11965
+ * A status or count label. Not a Base UI part, and not interactive: no hover or focus.
11966
+ * Colors are the emphasis levels (--sl-e-bg, --sl-e-fg, --sl-e-border), so data-emphasis,
11967
+ * data-status and data-color all recolor it. The default level is subtle, from
11968
+ * DEFAULT_LEVELS. The shape is radius.pill. Sizes are badge.* (tokens/component/badge.json).
11969
+ *
11970
+ * Text is the trigger style of the same tier (trigger-minimize, trigger-condense,
11971
+ * trigger-base): medium weight, and those three tiers already exist. subtitle is bold,
11972
+ * which would shout, and label only exists at base. Icons use icon-size of that same
11973
+ * tier (a badge icon is a mark beside the label, not a control that fills the line the
11974
+ * way a Button icon does).
11975
+ *
11976
+ * Min width equals the height on every badge, so a single digit is a circle and a
11977
+ * wider label is unchanged. Padding stays, so "12" does not touch the pill edges.
11978
+ */
11979
+
11980
+ .Badge {
11981
+ font-family: var(--sl-font-trigger-condense-font-family);
11982
+ font-size: var(--sl-font-trigger-condense-font-size);
11983
+ font-weight: var(--sl-font-trigger-condense-font-weight);
11984
+ line-height: var(--sl-font-trigger-condense-line-height);
11985
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
11986
+ display: inline-flex;
11987
+ align-items: center;
11988
+ justify-content: center;
11989
+ gap: var(--sl-badge-gap-condense);
11990
+ height: var(--sl-badge-height-condense);
11991
+ min-width: var(--sl-badge-height-condense);
11992
+ padding-inline: var(--sl-badge-padding-inline-condense);
11993
+ border: var(--sl-stroke-default) solid var(--sl-e-border);
11994
+ border-radius: var(--sl-radius-pill);
11995
+ background: var(--sl-e-bg);
11996
+ color: var(--sl-e-fg);
11997
+ white-space: nowrap;
11998
+ }
11999
+
12000
+ .Badge[data-size='minimize'] {
12001
+ font-family: var(--sl-font-trigger-minimize-font-family);
12002
+ font-size: var(--sl-font-trigger-minimize-font-size);
12003
+ font-weight: var(--sl-font-trigger-minimize-font-weight);
12004
+ line-height: var(--sl-font-trigger-minimize-line-height);
12005
+ letter-spacing: var(--sl-font-trigger-minimize-letter-spacing);
12006
+ gap: var(--sl-badge-gap-minimize);
12007
+ height: var(--sl-badge-height-minimize);
12008
+ min-width: var(--sl-badge-height-minimize);
12009
+ padding-inline: var(--sl-badge-padding-inline-minimize);
12010
+ }
12011
+
12012
+ .Badge[data-size='base'] {
12013
+ font-family: var(--sl-font-trigger-base-font-family);
12014
+ font-size: var(--sl-font-trigger-base-font-size);
12015
+ font-weight: var(--sl-font-trigger-base-font-weight);
12016
+ line-height: var(--sl-font-trigger-base-line-height);
12017
+ letter-spacing: var(--sl-font-trigger-base-letter-spacing);
12018
+ gap: var(--sl-badge-gap-base);
12019
+ height: var(--sl-badge-height-base);
12020
+ min-width: var(--sl-badge-height-base);
12021
+ padding-inline: var(--sl-badge-padding-inline-base);
12022
+ }
12023
+
12024
+ .Badge svg,
12025
+ .Badge .material-symbols-outlined {
12026
+ width: var(--sl-icon-size-condense);
12027
+ height: var(--sl-icon-size-condense);
12028
+ font-size: var(--sl-icon-size-condense);
12029
+ line-height: 1;
12030
+ flex-shrink: 0;
12031
+ }
12032
+
12033
+ .Badge[data-size='minimize'] svg,
12034
+ .Badge[data-size='minimize'] .material-symbols-outlined {
12035
+ width: var(--sl-icon-size-minimize);
12036
+ height: var(--sl-icon-size-minimize);
12037
+ font-size: var(--sl-icon-size-minimize);
12038
+ }
12039
+
12040
+ .Badge[data-size='base'] svg,
12041
+ .Badge[data-size='base'] .material-symbols-outlined {
12042
+ width: var(--sl-icon-size-base);
12043
+ height: var(--sl-icon-size-base);
12044
+ font-size: var(--sl-icon-size-base);
12045
+ }
12046
+
12047
+ /* A status dot, in the label color. */
12048
+ .Badge[data-dot]::before {
12049
+ content: '';
12050
+ width: var(--sl-badge-dot-condense);
12051
+ height: var(--sl-badge-dot-condense);
12052
+ border-radius: var(--sl-radius-pill);
12053
+ background: currentColor;
12054
+ flex-shrink: 0;
12055
+ }
12056
+
12057
+ .Badge[data-size='minimize'][data-dot]::before {
12058
+ width: var(--sl-badge-dot-minimize);
12059
+ height: var(--sl-badge-dot-minimize);
12060
+ }
12061
+
12062
+ .Badge[data-size='base'][data-dot]::before {
12063
+ width: var(--sl-badge-dot-base);
12064
+ height: var(--sl-badge-dot-base);
12065
+ }
12066
+
12067
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
12068
+ /*
12069
+ * DatePicker: a field that opens a calendar for one date or a period.
12070
+ * Not a Base UI part. The popup is Popover on a wide viewport and Drawer
12071
+ * below the md breakpoint. Calendar is the grid on its own; DatePresets is
12072
+ * the quick-selection list. Both are usable without the field.
12073
+ *
12074
+ * Concepts: calendar (day cell, range band, today ring), item (preset rows),
12075
+ * field (the trigger), emphasis bold (the selected day, via the default
12076
+ * emphasis level, so it follows data-color).
12077
+ *
12078
+ * Text styles, one whole style each: day numbers are trigger-condense and
12079
+ * selected days are selected-condense, weekday initials are eyebrow-minimize,
12080
+ * the month title is subtitle-base, a preset label is trigger-condense with
12081
+ * its hint in body-minimize, and the footer summary is body-condense.
12082
+ * The trigger text is text-body-base, the same style as Input.
12083
+ *
12084
+ * How many months are on screen is measured on the panel (40rem two months,
12085
+ * 32rem one, and one month in a drawer or for a coarse pointer under 48rem).
12086
+ * Those lengths are layout, not tokens. CSS only switches the preset row and
12087
+ * the sticky footer, from data-layout and data-compact.
12088
+ *
12089
+ * Keyboard (WAI-ARIA APG date picker dialog): Left/Right one day (they swap
12090
+ * in RTL), Up/Down one week, Home/End the week, PageUp/PageDown one month,
12091
+ * Shift+PageUp/PageDown one year, Enter/Space pick. With two months showing,
12092
+ * paging forward lands the focused day in the last column, so the view shifts
12093
+ * by one month. Delete or Backspace clears the draft. Escape drops a
12094
+ * half-picked range first, then closes. Escape in the month or year chooser
12095
+ * returns to the days. A range is a start click, then an end click; an end
12096
+ * before the start swaps. Hover or focus previews the band until the end is
12097
+ * chosen. Direction is read when the picker opens; a dir change while it is
12098
+ * open is not picked up.
12099
+ *
12100
+ * Day state: data-selected, data-range-start, data-range-end, data-in-range,
12101
+ * data-preview, data-today, data-outside-month, data-disabled, data-focused.
12102
+ * aria-selected is only the real value (the day, or the start and end).
12103
+ */
12104
+
12105
+ /* CALENDAR */
12106
+
12107
+ .Calendar {
12108
+ display: flex;
12109
+ flex-direction: column;
12110
+ gap: var(--sl-calendar-month-gap);
12111
+ min-width: 0;
12112
+ }
12113
+
12114
+ .DatePickerMonths {
12115
+ display: flex;
12116
+ flex-wrap: wrap;
12117
+ gap: var(--sl-calendar-month-gap);
12118
+ min-width: 0;
12119
+ }
12120
+
12121
+ .DatePickerNav {
12122
+ display: flex;
12123
+ align-items: center;
12124
+ gap: var(--sl-calendar-header-gap);
12125
+ flex: 1 0 100%;
12126
+ }
12127
+
12128
+ .DatePickerNav .DatePickerMonthTitle {
12129
+ flex: 1 1 auto;
12130
+ }
12131
+
12132
+ .DatePickerMonth {
12133
+ display: flex;
12134
+ flex-direction: column;
12135
+ gap: var(--sl-calendar-header-gap);
12136
+ min-width: 0;
12137
+ flex: 1 1 auto;
12138
+ }
12139
+
12140
+ .DatePickerMonthBar {
12141
+ display: flex;
12142
+ align-items: center;
12143
+ justify-content: space-between;
12144
+ gap: var(--sl-calendar-header-gap);
12145
+ min-height: var(--sl-control-height-sm);
12146
+ }
12147
+
12148
+ .DatePickerMonthSpacer {
12149
+ inline-size: var(--sl-control-height-sm);
12150
+ flex: 0 0 auto;
12151
+ }
12152
+
12153
+ .DatePickerMonthTitle {
12154
+ font-family: var(--sl-font-subtitle-base-font-family);
12155
+ font-size: var(--sl-font-subtitle-base-font-size);
12156
+ font-weight: var(--sl-font-subtitle-base-font-weight);
12157
+ line-height: var(--sl-font-subtitle-base-line-height);
12158
+ letter-spacing: var(--sl-font-subtitle-base-letter-spacing);
12159
+ outline: none;
12160
+ margin: 0;
12161
+ padding: var(--sl-space-1) var(--sl-space-2);
12162
+ border: 0;
12163
+ border-radius: var(--sl-radius-control);
12164
+ background: transparent;
12165
+ color: var(--sl-text-primary);
12166
+ cursor: pointer;
12167
+ }
12168
+
12169
+ .DatePickerMonthTitle:hover {
12170
+ background: var(--sl-item-background-hover);
12171
+ }
12172
+
12173
+ .DatePickerMonthTitle:focus-visible {
12174
+ outline: var(--sl-focus-outline);
12175
+ outline-offset: var(--sl-focus-outline-offset);
12176
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
12177
+ }
12178
+
12179
+ .CalendarGrid {
12180
+ display: flex;
12181
+ flex-direction: column;
12182
+ gap: var(--sl-calendar-grid-gap);
12183
+ }
12184
+
12185
+ .Calendar,
12186
+ .DatePickerPanel {
12187
+ --sl-calendar-cell: var(--sl-calendar-day-size);
12188
+ }
12189
+
12190
+ .DatePickerPanel[data-touch] {
12191
+ --sl-calendar-cell: max(var(--sl-calendar-day-size), var(--sl-a11y-min-touch-target));
12192
+ }
12193
+
12194
+ @media (pointer: coarse) {
12195
+ .Calendar {
12196
+ --sl-calendar-cell: max(var(--sl-calendar-day-size), var(--sl-a11y-min-touch-target));
12197
+ }
12198
+ }
12199
+
12200
+ .CalendarWeek {
12201
+ display: grid;
12202
+ grid-template-columns: repeat(7, var(--sl-calendar-cell));
12203
+ column-gap: 0;
12204
+ row-gap: var(--sl-calendar-grid-gap);
12205
+ }
12206
+
12207
+ .CalendarGrid:has(.CalendarWeekNumber) .CalendarWeek {
12208
+ grid-template-columns: auto repeat(7, var(--sl-calendar-cell));
12209
+ }
12210
+
12211
+ .CalendarWeekday,
12212
+ .CalendarWeekNumber {
12213
+ font-family: var(--sl-font-eyebrow-minimize-font-family);
12214
+ font-size: var(--sl-font-eyebrow-minimize-font-size);
12215
+ font-weight: var(--sl-font-eyebrow-minimize-font-weight);
12216
+ line-height: var(--sl-font-eyebrow-minimize-line-height);
12217
+ letter-spacing: var(--sl-font-eyebrow-minimize-letter-spacing);
12218
+ text-transform: var(--sl-font-eyebrow-minimize-text-transform);
12219
+ display: grid;
12220
+ place-items: center;
12221
+ min-block-size: var(--sl-space-6);
12222
+ color: var(--sl-calendar-weekday-color);
12223
+ text-decoration: none;
12224
+ }
12225
+
12226
+ .CalendarWeekNumber {
12227
+ padding-inline: var(--sl-space-1);
12228
+ }
12229
+
12230
+ .CalendarDay {
12231
+ font-family: var(--sl-font-trigger-condense-font-family);
12232
+ font-size: var(--sl-font-trigger-condense-font-size);
12233
+ font-weight: var(--sl-font-trigger-condense-font-weight);
12234
+ line-height: var(--sl-font-trigger-condense-line-height);
12235
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
12236
+ position: relative;
12237
+ display: grid;
12238
+ place-items: center;
12239
+ box-sizing: border-box;
12240
+ inline-size: 100%;
12241
+ aspect-ratio: 1;
12242
+ min-inline-size: 0;
12243
+ min-block-size: 0;
12244
+ padding: 0;
12245
+ border: 0;
12246
+ border-radius: var(--sl-calendar-day-radius);
12247
+ outline: none;
12248
+ background: transparent;
12249
+ color: var(--sl-calendar-day-color);
12250
+ cursor: pointer;
12251
+ }
12252
+
12253
+ .CalendarDay:focus-visible {
12254
+ outline: var(--sl-focus-outline);
12255
+ outline-offset: var(--sl-focus-outline-offset);
12256
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
12257
+ }
12258
+
12259
+ .CalendarDay--empty {
12260
+ cursor: default;
12261
+ pointer-events: none;
12262
+ }
12263
+
12264
+ .CalendarDayNumber {
12265
+ position: relative;
12266
+ z-index: 1;
12267
+ }
12268
+
12269
+ .CalendarDay:hover:not([data-disabled]):not([data-selected]) {
12270
+ background: var(--sl-calendar-day-background-hover);
12271
+ }
12272
+
12273
+ .CalendarDay[data-outside-month] {
12274
+ color: var(--sl-calendar-day-color-outside);
12275
+ }
12276
+
12277
+ .CalendarDay[data-disabled] {
12278
+ color: var(--sl-calendar-day-color-disabled);
12279
+ cursor: default;
12280
+ }
12281
+
12282
+ .CalendarDay[data-selected] {
12283
+ font-family: var(--sl-font-selected-condense-font-family);
12284
+ font-size: var(--sl-font-selected-condense-font-size);
12285
+ font-weight: var(--sl-font-selected-condense-font-weight);
12286
+ line-height: var(--sl-font-selected-condense-line-height);
12287
+ letter-spacing: var(--sl-font-selected-condense-letter-spacing);
12288
+ }
12289
+
12290
+ .CalendarDay[data-selected]:not([data-range-start]):not([data-range-end]) {
12291
+ background: var(--sl-e-bg);
12292
+ color: var(--sl-e-fg);
12293
+ }
12294
+
12295
+ .CalendarDay[data-range-start],
12296
+ .CalendarDay[data-range-end] {
12297
+ overflow: hidden;
12298
+ background: transparent;
12299
+ }
12300
+
12301
+ .CalendarDay[data-range-start] .CalendarDayNumber,
12302
+ .CalendarDay[data-range-end] .CalendarDayNumber {
12303
+ display: grid;
12304
+ place-items: center;
12305
+ inline-size: 100%;
12306
+ block-size: 100%;
12307
+ border-radius: var(--sl-calendar-day-radius);
12308
+ background: var(--sl-e-bg);
12309
+ color: var(--sl-e-fg);
12310
+ }
12311
+
12312
+ .CalendarDay[data-in-range],
12313
+ .CalendarDay[data-preview]:not([data-selected]) {
12314
+ border-radius: 0;
12315
+ background: var(--sl-calendar-range-background);
12316
+ color: var(--sl-calendar-range-color);
12317
+ }
12318
+
12319
+ .CalendarDay[data-range-start]::before,
12320
+ .CalendarDay[data-range-end]::before {
12321
+ content: '';
12322
+ position: absolute;
12323
+ inset: 0;
12324
+ z-index: 0;
12325
+ background: linear-gradient(to right, transparent 50%, var(--sl-calendar-range-background) 50%);
12326
+ }
12327
+
12328
+ .CalendarDay[data-range-end]::before {
12329
+ background: linear-gradient(to left, transparent 50%, var(--sl-calendar-range-background) 50%);
12330
+ }
12331
+
12332
+ [dir='rtl'] .CalendarDay[data-range-start]::before {
12333
+ background: linear-gradient(to left, transparent 50%, var(--sl-calendar-range-background) 50%);
12334
+ }
12335
+
12336
+ [dir='rtl'] .CalendarDay[data-range-end]::before {
12337
+ background: linear-gradient(to right, transparent 50%, var(--sl-calendar-range-background) 50%);
12338
+ }
12339
+
12340
+ .CalendarDay[data-range-start][data-range-end]::before {
12341
+ content: none;
12342
+ }
12343
+
12344
+ .CalendarDay[data-focused] {
12345
+ z-index: 1;
12346
+ }
12347
+
12348
+ .CalendarDay[data-today] .CalendarDayNumber {
12349
+ box-shadow: inset 0 0 0 var(--sl-stroke-default) var(--sl-calendar-today-ring);
12350
+ border-radius: var(--sl-calendar-day-radius);
12351
+ padding-inline: var(--sl-space-1);
12352
+ }
12353
+
12354
+ /* The selected fill is the bold accent, the same hue as the today ring, so the ring switches to the text color. */
12355
+ .CalendarDay[data-today][data-selected] .CalendarDayNumber {
12356
+ box-shadow: inset 0 0 0 var(--sl-stroke-default) var(--sl-e-fg);
12357
+ }
12358
+
12359
+ [data-theme$='high-contrast'] .CalendarDay[data-in-range],
12360
+ [data-theme$='high-contrast'] .CalendarDay[data-preview]:not([data-selected]) {
12361
+ box-shadow: inset 0 calc(var(--sl-stroke-default) * -1) 0 var(--sl-border-accent);
12362
+ }
12363
+
12364
+ .CalendarChooser {
12365
+ display: flex;
12366
+ flex-direction: column;
12367
+ gap: var(--sl-calendar-header-gap);
12368
+ }
12369
+
12370
+ .CalendarChooserGrid {
12371
+ display: grid;
12372
+ grid-template-columns: repeat(3, minmax(0, 1fr));
12373
+ gap: var(--sl-calendar-grid-gap);
12374
+ }
12375
+
12376
+ .CalendarChoice {
12377
+ font-family: var(--sl-font-trigger-condense-font-family);
12378
+ font-size: var(--sl-font-trigger-condense-font-size);
12379
+ font-weight: var(--sl-font-trigger-condense-font-weight);
12380
+ line-height: var(--sl-font-trigger-condense-line-height);
12381
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
12382
+ outline: none;
12383
+ min-block-size: var(--sl-control-height-sm);
12384
+ padding: var(--sl-space-1) var(--sl-space-2);
12385
+ border: 0;
12386
+ border-radius: var(--sl-radius-control);
12387
+ background: transparent;
12388
+ color: var(--sl-text-primary);
12389
+ cursor: pointer;
12390
+ }
12391
+
12392
+ .CalendarChoice:hover:not([aria-disabled='true']) {
12393
+ background: var(--sl-item-background-hover);
12394
+ }
12395
+
12396
+ .CalendarChoice:focus-visible {
12397
+ outline: var(--sl-focus-outline);
12398
+ outline-offset: var(--sl-focus-outline-offset);
12399
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
12400
+ }
12401
+
12402
+ .CalendarChoice[aria-disabled='true'] {
12403
+ color: var(--sl-calendar-day-color-disabled);
12404
+ cursor: default;
12405
+ }
12406
+
12407
+ /* PRESETS */
12408
+
12409
+ .DatePickerPresets {
12410
+ display: flex;
12411
+ flex-direction: column;
12412
+ gap: var(--sl-space-1);
12413
+ min-width: 0;
12414
+ }
12415
+
12416
+ .DatePickerPresets[data-layout='row'] {
12417
+ flex-direction: row;
12418
+ overflow-x: auto;
12419
+ }
12420
+
12421
+ .DatePickerPreset {
12422
+ font-family: var(--sl-font-trigger-condense-font-family);
12423
+ font-size: var(--sl-font-trigger-condense-font-size);
12424
+ font-weight: var(--sl-font-trigger-condense-font-weight);
12425
+ line-height: var(--sl-font-trigger-condense-line-height);
12426
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
12427
+ outline: none;
12428
+ display: flex;
12429
+ flex-direction: column;
12430
+ align-items: flex-start;
12431
+ gap: var(--sl-space-0-5);
12432
+ inline-size: 100%;
12433
+ padding: var(--sl-item-padding-block) var(--sl-item-padding-inline);
12434
+ border: 0;
12435
+ border-radius: var(--sl-item-radius);
12436
+ background: transparent;
12437
+ color: var(--sl-item-color);
12438
+ text-align: start;
12439
+ cursor: pointer;
12440
+ }
12441
+
12442
+ .DatePickerPresets[data-layout='row'] .DatePickerPreset {
12443
+ flex-direction: row;
12444
+ align-items: baseline;
12445
+ inline-size: auto;
12446
+ white-space: nowrap;
12447
+ }
12448
+
12449
+ .DatePickerPreset:hover:not([data-disabled]) {
12450
+ background: var(--sl-item-background-hover);
12451
+ }
12452
+
12453
+ .DatePickerPreset:focus-visible {
12454
+ outline: var(--sl-focus-outline);
12455
+ outline-offset: var(--sl-focus-outline-offset);
12456
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
12457
+ }
12458
+
12459
+ .DatePickerPreset[data-checked] {
12460
+ background: var(--sl-item-background-selected);
12461
+ color: var(--sl-item-color-selected);
12462
+ }
12463
+
12464
+ .DatePickerPreset[data-disabled] {
12465
+ color: var(--sl-text-disabled);
12466
+ cursor: default;
12467
+ }
12468
+
12469
+ .DatePickerPresetHint {
12470
+ font-family: var(--sl-font-body-minimize-font-family);
12471
+ font-size: var(--sl-font-body-minimize-font-size);
12472
+ font-weight: var(--sl-font-body-minimize-font-weight);
12473
+ line-height: var(--sl-font-body-minimize-line-height);
12474
+ letter-spacing: var(--sl-font-body-minimize-letter-spacing);
12475
+ color: var(--sl-text-tertiary);
12476
+ }
12477
+
12478
+ .DatePickerPreset[data-checked] .DatePickerPresetHint {
12479
+ color: var(--sl-item-color-selected);
12480
+ }
12481
+
12482
+ /* PICKER */
12483
+
12484
+ .DatePickerField {
12485
+ position: relative;
12486
+ display: flex;
12487
+ align-items: center;
12488
+ min-width: 0;
12489
+ }
12490
+
12491
+ .DatePickerField .DatePickerTrigger {
12492
+ box-sizing: border-box;
12493
+ color: var(--sl-field-color);
12494
+ background: var(--sl-field-background);
12495
+ border: var(--sl-field-border-width) solid var(--sl-field-border-color);
12496
+ border-radius: var(--sl-field-radius);
12497
+ transition: var(--sl-field-transition);
12498
+ outline: none;
12499
+ font-family: var(--sl-font-body-base-font-family);
12500
+ font-size: var(--sl-font-body-base-font-size);
12501
+ font-weight: var(--sl-font-body-base-font-weight);
12502
+ line-height: var(--sl-font-body-base-line-height);
12503
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
12504
+ outline: none;
12505
+ display: inline-flex;
12506
+ align-items: center;
12507
+ gap: var(--sl-gap-control);
12508
+ inline-size: 100%;
12509
+ block-size: var(--sl-control-height-md);
12510
+ padding-inline: var(--sl-control-padding-inline);
12511
+ text-align: start;
12512
+ cursor: pointer;
12513
+ }
12514
+
12515
+ .DatePickerTrigger:disabled {
12516
+ color: var(--sl-text-disabled);
12517
+ cursor: default;
12518
+ }
12519
+
12520
+ .DatePickerField .DatePickerTrigger:focus-visible {
12521
+ outline: var(--sl-focus-outline);
12522
+ outline-offset: var(--sl-focus-outline-offset);
12523
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
12524
+ }
12525
+
12526
+ .DatePickerValue[data-placeholder] {
12527
+ color: var(--sl-text-tertiary);
12528
+ }
12529
+
12530
+ .DatePickerClear {
12531
+ position: absolute;
12532
+ inset-inline-end: var(--sl-space-1);
12533
+ z-index: 1;
12534
+ }
12535
+
12536
+ .DatePickerTrigger:has(~ .DatePickerClear) {
12537
+ padding-inline-end: var(--sl-control-height-sm);
12538
+ }
12539
+
12540
+ .DatePickerPopup {
12541
+ /* 52rem fits two months and the preset column; three months ask for 64rem. Layout, not a brand size. */
12542
+ inline-size: min(var(--available-width, 100vw), 52rem);
12543
+ max-inline-size: var(--available-width, 100vw);
12544
+ padding: 0;
12545
+ }
12546
+
12547
+ .DatePickerPopup[data-months='3'] {
12548
+ inline-size: min(var(--available-width, 100vw), 64rem);
12549
+ }
12550
+
12551
+ .DatePickerPanel {
12552
+ display: grid;
12553
+ /* 11rem is the preset column. Layout, not a brand size: wide enough for "Year to date" and a hint. */
12554
+ grid-template-columns: 11rem minmax(0, 1fr);
12555
+ align-items: start;
12556
+ gap: var(--sl-calendar-month-gap);
12557
+ padding: var(--sl-calendar-panel-padding);
12558
+ min-width: 0;
12559
+ }
12560
+
12561
+ .DatePickerPanel .DatePickerPresets {
12562
+ grid-column: 1;
12563
+ grid-row: 1 / span 2;
12564
+ inline-size: auto;
12565
+ }
12566
+
12567
+ .DatePickerPanel .Calendar {
12568
+ grid-column: 2;
12569
+ grid-row: 1;
12570
+ min-width: 0;
12571
+ }
12572
+
12573
+ .DatePickerPanel:not(:has(.DatePickerPresets)) {
12574
+ grid-template-columns: minmax(0, 1fr);
12575
+ }
12576
+
12577
+ .DatePickerPanel:not(:has(.DatePickerPresets)) .Calendar,
12578
+ .DatePickerPanel:not(:has(.DatePickerPresets)) .DatePickerFooter {
12579
+ grid-column: 1;
12580
+ }
12581
+
12582
+ .DatePickerFooter {
12583
+ display: flex;
12584
+ align-items: center;
12585
+ justify-content: space-between;
12586
+ gap: var(--sl-space-3);
12587
+ grid-column: 2;
12588
+ grid-row: 2;
12589
+ }
12590
+
12591
+ .DatePickerSummary {
12592
+ font-family: var(--sl-font-body-condense-font-family);
12593
+ font-size: var(--sl-font-body-condense-font-size);
12594
+ font-weight: var(--sl-font-body-condense-font-weight);
12595
+ line-height: var(--sl-font-body-condense-line-height);
12596
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
12597
+ margin: 0;
12598
+ color: var(--sl-text-secondary);
12599
+ }
12600
+
12601
+ .DatePickerActions {
12602
+ display: flex;
12603
+ gap: var(--sl-space-2);
12604
+ margin-inline-start: auto;
12605
+ }
12606
+
12607
+ /* Presets become a row once the measured panel is under 40rem, or the popup is a drawer. */
12608
+ .DatePickerPanel[data-layout='row'],
12609
+ .DatePickerPanel[data-layout='row']:not(:has(.DatePickerPresets)) {
12610
+ grid-template-columns: minmax(0, 1fr);
12611
+ }
12612
+
12613
+ .DatePickerPanel[data-layout='row'] .DatePickerPresets,
12614
+ .DatePickerPanel[data-layout='row'] .Calendar,
12615
+ .DatePickerPanel[data-layout='row'] .DatePickerFooter {
12616
+ grid-column: 1;
12617
+ grid-row: auto;
12618
+ }
12619
+
12620
+ .DatePickerPanel[data-compact] .DatePickerFooter {
12621
+ position: sticky;
12622
+ inset-block-end: 0;
12623
+ flex-wrap: wrap;
12624
+ background: var(--sl-popup-background);
12625
+ }
12626
+
12627
+ /* The action row shrinks to its buttons, so a percentage width on Apply never
12628
+ resolves. A 100% basis wraps Apply onto its own row of the footer. */
12629
+ .DatePickerPanel[data-compact] .DatePickerActions {
12630
+ flex-basis: 100%;
12631
+ flex-wrap: wrap;
12632
+ justify-content: flex-end;
12633
+ margin-inline-start: 0;
12634
+ }
12635
+
12636
+ .DatePickerPanel[data-compact] .DatePickerApply {
12637
+ flex-basis: 100%;
12638
+ }
12639
+
12640
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
12641
+ /* Money field
12642
+ *
12643
+ * An amount of money, built on Number field. The value is an integer in minor units
12644
+ * (cents, yen, fils) so 0.1 + 0.2 and 1.005 * 100 cannot drift, and so the number matches
12645
+ * what a payment API sends. Number field counts in major units; Money field converts at
12646
+ * the edge and rounds half away from zero. The default maximum is 10^15 - 1 minor
12647
+ * units, so the major amount stays inside 15 significant digits. Changing currency
12648
+ * keeps the number the person typed and re-rounds it to the new currency's digits
12649
+ * (12.50 USD becomes 13 JPY). There is no exchange rate. When the app
12650
+ * controls both the value and the currency, it decides whether to apply that rounding:
12651
+ * onValueChange still reports the re-rounded minor units.
12652
+ *
12653
+ * Keyboard is Number field's: ArrowUp and ArrowDown step one major unit, Shift steps 100
12654
+ * major units, Alt steps one minor unit, Home and End jump to the minimum and maximum.
12655
+ * The currency symbol is not in the text, so the caret does not fight it. A fixed symbol
12656
+ * is aria-hidden; the currency name is in the input's accessible description. A picker
12657
+ * is its own tab stop, before the input when the locale puts the symbol first and after
12658
+ * it when the locale puts the symbol last.
12659
+ *
12660
+ * State on the root: data-currency (USD), data-affix (start or end), data-affix-kind
12661
+ * (symbol or picker), data-negative (below zero; set data-color on the field to color
12662
+ * it, never on by default), data-align (start or end),
12663
+ * data-size (xs, sm, md, lg), data-readonly, plus data-invalid, data-disabled,
12664
+ * data-focused and data-scrubbing.
12665
+ *
12666
+ * The affix (symbol or picker) is drawn inside the field so it can later be lifted into
12667
+ * a general Input affix for units, https://, or @. Position comes from the locale, with
12668
+ * logical properties so RTL mirrors it. The group, not the input, carries the field
12669
+ * border, hover, focus halo, invalid edge and disabled fill, so the affix reads as part
12670
+ * of the field.
12671
+ */
12672
+
12673
+ /* ============================================
12674
+ FIELD
12675
+ ============================================ */
12676
+
12677
+ .MoneyField {
12678
+ display: inline-flex;
12679
+ flex-direction: column;
12680
+ gap: var(--sl-field-gap);
12681
+ width: 100%;
12682
+ }
12683
+
12684
+ .MoneyFieldGroup {
12685
+ box-sizing: border-box;
12686
+ color: var(--sl-field-color);
12687
+ background: var(--sl-field-background);
12688
+ border: var(--sl-field-border-width) solid var(--sl-field-border-color);
12689
+ border-radius: var(--sl-field-radius);
12690
+ transition: var(--sl-field-transition);
12691
+ outline: none;
12692
+ font-family: var(--sl-font-body-base-font-family);
12693
+ font-size: var(--sl-font-body-base-font-size);
12694
+ font-weight: var(--sl-font-body-base-font-weight);
12695
+ line-height: var(--sl-font-body-base-line-height);
12696
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
12697
+ display: flex;
12698
+ align-items: stretch;
12699
+ width: 100%;
12700
+ height: var(--sl-control-height-md);
12701
+ padding: 0;
12702
+ }
12703
+
12704
+ .MoneyField[data-size='xs'] .MoneyFieldGroup {
12705
+ font-family: var(--sl-font-body-minimize-font-family);
12706
+ font-size: var(--sl-font-body-minimize-font-size);
12707
+ font-weight: var(--sl-font-body-minimize-font-weight);
12708
+ line-height: var(--sl-font-body-minimize-line-height);
12709
+ letter-spacing: var(--sl-font-body-minimize-letter-spacing);
12710
+ height: var(--sl-control-height-xs);
12711
+ }
12712
+
12713
+ .MoneyField[data-size='sm'] .MoneyFieldGroup {
12714
+ font-family: var(--sl-font-body-condense-font-family);
12715
+ font-size: var(--sl-font-body-condense-font-size);
12716
+ font-weight: var(--sl-font-body-condense-font-weight);
12717
+ line-height: var(--sl-font-body-condense-line-height);
12718
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
12719
+ height: var(--sl-control-height-sm);
12720
+ }
12721
+
12722
+ .MoneyField[data-size='lg'] .MoneyFieldGroup {
12723
+ font-family: var(--sl-font-body-magnify-font-family);
12724
+ font-size: var(--sl-font-body-magnify-font-size);
12725
+ font-weight: var(--sl-font-body-magnify-font-weight);
12726
+ line-height: var(--sl-font-body-magnify-line-height);
12727
+ letter-spacing: var(--sl-font-body-magnify-letter-spacing);
12728
+ height: var(--sl-control-height-lg);
12729
+ }
12730
+
12731
+ .MoneyFieldGroup .MoneyFieldInput,
12732
+ .MoneyFieldAffix,
12733
+ .MoneyFieldGroup .MoneyFieldCurrencyTrigger {
12734
+ font: inherit;
12735
+ }
12736
+
12737
+ .MoneyFieldGroup .MoneyFieldInput {
12738
+ flex: 1;
12739
+ min-inline-size: 0;
12740
+ height: auto;
12741
+ border: 0;
12742
+ border-radius: 0;
12743
+ background: transparent;
12744
+ box-shadow: none;
12745
+ outline: none;
12746
+ font-variant-numeric: tabular-nums;
12747
+ }
12748
+
12749
+ .MoneyFieldGroup .MoneyFieldInput:hover,
12750
+ .MoneyFieldGroup .MoneyFieldInput:focus,
12751
+ .MoneyField[data-invalid] .MoneyFieldInput,
12752
+ .MoneyField[data-invalid] .MoneyFieldInput:focus,
12753
+ .MoneyField[data-disabled] .MoneyFieldInput {
12754
+ border-color: transparent;
12755
+ background: transparent;
12756
+ box-shadow: none;
12757
+ }
12758
+
12759
+ /* A symbol brings its own padding. A picker has a divider, so the amount keeps its inset. */
12760
+ .MoneyField[data-affix-kind='symbol'][data-affix='start'] .MoneyFieldInput {
12761
+ padding-inline-start: 0;
12762
+ }
12763
+
12764
+ .MoneyField[data-affix-kind='symbol'][data-affix='end']:not([data-steppers]) .MoneyFieldInput {
12765
+ padding-inline-end: 0;
12766
+ }
12767
+
12768
+ /* Number field always pads for its steppers. Those buttons are absent unless asked for. */
12769
+ .MoneyField:not([data-steppers]) .MoneyFieldInput {
12770
+ padding-inline-end: var(--sl-control-padding-inline);
12771
+ }
12772
+
12773
+ .MoneyField[data-size='xs']:not([data-steppers]) .MoneyFieldInput {
12774
+ padding-inline-end: var(--sl-control-padding-inline-xs);
12775
+ }
12776
+
12777
+ .MoneyField[data-size='sm']:not([data-steppers]) .MoneyFieldInput {
12778
+ padding-inline-end: var(--sl-control-padding-inline-sm);
12779
+ }
12780
+
12781
+ .MoneyField[data-size='lg']:not([data-steppers]) .MoneyFieldInput {
12782
+ padding-inline-end: var(--sl-control-padding-inline-lg);
12783
+ }
12784
+
12785
+ .MoneyField[data-align='end'] .MoneyFieldInput {
12786
+ text-align: end;
12787
+ }
12788
+
12789
+ .MoneyField[data-align='start'] .MoneyFieldInput {
12790
+ text-align: start;
12791
+ }
12792
+
12793
+ .MoneyFieldGroup:hover:not(:focus-within) {
12794
+ border-color: var(--sl-field-border-color-hover);
12795
+ }
12796
+
12797
+ .MoneyFieldGroup:focus-within,
12798
+ .MoneyField[data-focused] .MoneyFieldGroup {
12799
+ border-color: var(--sl-field-border-color-focus);
12800
+ box-shadow: var(--sl-field-shadow-focus);
12801
+ }
12802
+
12803
+ .MoneyField[data-invalid] .MoneyFieldGroup {
12804
+ border-color: var(--sl-field-border-color-error);
12805
+ }
12806
+
12807
+ .MoneyField[data-invalid] .MoneyFieldGroup:focus-within,
12808
+ .MoneyField[data-invalid][data-focused] .MoneyFieldGroup {
12809
+ border-color: var(--sl-field-border-color-error);
12810
+ box-shadow: var(--sl-field-shadow-focus-error);
12811
+ }
12812
+
12813
+ .MoneyField[data-disabled] .MoneyFieldGroup {
12814
+ background: var(--sl-field-background-disabled);
12815
+ cursor: not-allowed;
12816
+ }
12817
+
12818
+ .MoneyField[data-readonly] .MoneyFieldInput {
12819
+ cursor: default;
12820
+ }
12821
+
12822
+ /* The palette is the one on the field. An ancestor data-color does not recolor a balance. */
12823
+ .MoneyField[data-negative][data-color] .MoneyFieldInput {
12824
+ color: var(--sl-scope-fg);
12825
+ }
12826
+
12827
+ .MoneyField[data-scrubbing] .MoneyFieldInput {
12828
+ cursor: ns-resize;
12829
+ }
12830
+
12831
+ /* The sign toggle is for coarse pointers: an iOS decimal keypad has no minus key. */
12832
+ .MoneyFieldSign {
12833
+ display: none;
12834
+ align-self: center;
12835
+ flex: none;
12836
+ }
12837
+
12838
+ @media (pointer: coarse) {
12839
+ .MoneyFieldSign {
12840
+ display: inline-flex;
12841
+ }
12842
+ }
12843
+
12844
+ /* ============================================
12845
+ AFFIX
12846
+ ============================================ */
12847
+
12848
+ .MoneyFieldAffix {
12849
+ display: inline-flex;
12850
+ align-items: center;
12851
+ flex: none;
12852
+ padding-inline: var(--sl-control-padding-inline);
12853
+ color: var(--sl-field-affix-color);
12854
+ user-select: none;
12855
+ }
12856
+
12857
+ .MoneyField[data-size='xs'] .MoneyFieldAffix {
12858
+ padding-inline: var(--sl-control-padding-inline-xs);
12859
+ }
12860
+
12861
+ .MoneyField[data-size='sm'] .MoneyFieldAffix {
12862
+ padding-inline: var(--sl-control-padding-inline-sm);
12863
+ }
12864
+
12865
+ .MoneyField[data-size='lg'] .MoneyFieldAffix {
12866
+ padding-inline: var(--sl-control-padding-inline-lg);
12867
+ }
12868
+
12869
+ /* ============================================
12870
+ CURRENCY SELECT
12871
+ ============================================ */
12872
+
12873
+ .MoneyFieldCurrency {
12874
+ display: flex;
12875
+ align-self: stretch;
12876
+ flex: none;
12877
+ }
12878
+
12879
+ .MoneyFieldCurrencyTrigger {
12880
+ display: inline-flex;
12881
+ align-items: center;
12882
+ align-self: stretch;
12883
+ flex: none;
12884
+ gap: var(--sl-space-1);
12885
+ height: auto;
12886
+ min-height: 0;
12887
+ padding-inline: var(--sl-control-padding-inline);
12888
+ border: 0;
12889
+ border-radius: 0;
12890
+ background: transparent;
12891
+ box-shadow: none;
12892
+ color: var(--sl-field-affix-color);
12893
+ }
12894
+
12895
+ .MoneyField[data-size='xs'] .MoneyFieldCurrencyTrigger {
12896
+ padding-inline: var(--sl-control-padding-inline-xs);
12897
+ }
12898
+
12899
+ .MoneyField[data-size='sm'] .MoneyFieldCurrencyTrigger {
12900
+ padding-inline: var(--sl-control-padding-inline-sm);
12901
+ }
12902
+
12903
+ .MoneyField[data-size='lg'] .MoneyFieldCurrencyTrigger {
12904
+ padding-inline: var(--sl-control-padding-inline-lg);
12905
+ }
12906
+
12907
+ .MoneyField[data-affix='start'] .MoneyFieldCurrency {
12908
+ border-inline-end: var(--sl-field-border-width) solid var(--sl-field-border-color);
12909
+ }
12910
+
12911
+ .MoneyField[data-affix='end'] .MoneyFieldCurrency {
12912
+ border-inline-start: var(--sl-field-border-width) solid var(--sl-field-border-color);
12913
+ }
12914
+
12915
+ .MoneyFieldCurrencyTrigger:hover,
12916
+ .MoneyFieldCurrencyTrigger:focus,
12917
+ .MoneyFieldCurrencyTrigger[data-popup-open],
12918
+ .MoneyFieldCurrencyTrigger[aria-expanded='true'] {
12919
+ border-color: transparent;
12920
+ background: transparent;
12921
+ box-shadow: none;
12922
+ color: var(--sl-text-primary);
12923
+ }
12924
+
12925
+ /* The group halo says the field is focused. This says the picker, not the amount, has the caret. */
12926
+ .MoneyFieldCurrencyTrigger:focus-visible {
12927
+ outline: var(--sl-focus-outline);
12928
+ outline-offset: var(--sl-focus-outline-offset-inset);
12929
+ }
12930
+
12931
+ /* The picker is its own field, so it does not take the amount's label. */
12932
+ .MoneyFieldCurrencyField,
12933
+ .MoneyFieldGroup .ComboboxRoot {
12934
+ display: contents;
12935
+ }
12936
+
12937
+ .MoneyFieldCurrencyIcon {
12938
+ width: var(--sl-icon-size-base);
12939
+ height: var(--sl-icon-size-base);
12940
+ font-size: var(--sl-icon-size-base);
12941
+ }
12942
+
12943
+ .MoneyField[data-size='xs'] .MoneyFieldCurrencyIcon {
12944
+ width: var(--sl-icon-size-minimize);
12945
+ height: var(--sl-icon-size-minimize);
12946
+ font-size: var(--sl-icon-size-minimize);
12947
+ }
12948
+
12949
+ .MoneyField[data-size='sm'] .MoneyFieldCurrencyIcon {
12950
+ width: var(--sl-icon-size-condense);
12951
+ height: var(--sl-icon-size-condense);
12952
+ font-size: var(--sl-icon-size-condense);
12953
+ }
12954
+
12955
+ .MoneyField[data-size='lg'] .MoneyFieldCurrencyIcon {
12956
+ width: var(--sl-icon-size-magnify);
12957
+ height: var(--sl-icon-size-magnify);
12958
+ font-size: var(--sl-icon-size-magnify);
12959
+ }
12960
+
12961
+ .MoneyFieldCurrencyPopup {
12962
+ min-inline-size: var(--sl-money-field-picker-min-inline-size);
12963
+ }
12964
+
12965
+ .MoneyFieldCurrencyItem {
12966
+ display: flex;
12967
+ align-items: center;
12968
+ justify-content: space-between;
12969
+ gap: var(--sl-space-4);
12970
+ width: 100%;
12971
+ }
12972
+
12973
+ .MoneyFieldCurrencySymbol {
12974
+ color: var(--sl-text-secondary);
12975
+ }
12976
+
12977
+ .MoneyFieldCurrencyPopup .ComboboxInput {
12978
+ font-family: var(--sl-font-body-base-font-family);
12979
+ font-size: var(--sl-font-body-base-font-size);
12980
+ font-weight: var(--sl-font-body-base-font-weight);
12981
+ line-height: var(--sl-font-body-base-line-height);
12982
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
12983
+ }
12984
+
12985
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
12986
+ /* ListDetail
12987
+ *
12988
+ * The detail of one item, next to its list. Not a Base UI part. It is a Splitter
12989
+ * when this element is at least list-detail.split-min-width wide, measured on the
12990
+ * element itself so it still works inside another panel. Narrower, the detail is
12991
+ * the existing Drawer (the default) or it replaces the list, which stays mounted
12992
+ * and hidden so its scroll position survives Back.
12993
+ *
12994
+ * The list stays in the splitter's first panel whether the detail is open, closed,
12995
+ * or in a drawer, so its scroll survives. The detail is portaled into a node the
12996
+ * component created, and that node moves. The list sits on the page surface. The
12997
+ * detail sits on surface.raised: a pane
12998
+ * beside the list, one step off the page, with the splitter line as the only
12999
+ * divider. A modal surface would make the pane look like a dialog stuck in the
13000
+ * layout. Drawer mode does not restyle that; it uses the Drawer's own modal
13001
+ * surface, title and Close, so it matches every other drawer.
13002
+ *
13003
+ * The header title is text-title-condense. title-amplify is for a dialog or a
13004
+ * drawer, a layer over the page. A pane heading shares the view with the list,
13005
+ * so the condensed title fits the row. Close is a quiet icon-only Button: a
13006
+ * text Close would compete with the title and the actions in a short header.
13007
+ * Page mode puts Back, icon and word, where Close was.
13008
+ *
13009
+ * Focus moves to the heading when the detail opens, and back to the row when it
13010
+ * closes. Changing the title because another row was picked does not move focus.
13011
+ * Escape closes only when it bubbles out of the detail, so an open menu handles
13012
+ * it first. Nothing listens on window. Page changes are announced by that focus
13013
+ * move; there is no live region.
13014
+ *
13015
+ * data-layout is split, drawer or page. data-open is set while the detail is open.
13016
+ */
13017
+
13018
+ .ListDetail {
13019
+ display: flex;
13020
+ flex-direction: column;
13021
+ width: 100%;
13022
+ height: 100%;
13023
+ min-width: 0;
13024
+ min-height: 0;
13025
+ }
13026
+
13027
+ .ListDetailHost,
13028
+ .ListDetailSlot,
13029
+ .ListDetailSplit,
13030
+ .ListDetailList,
13031
+ .ListDetailDetail {
13032
+ display: flex;
13033
+ flex-direction: column;
13034
+ min-width: 0;
13035
+ min-height: 0;
13036
+ height: 100%;
13037
+ flex: 1;
13038
+ }
13039
+
13040
+ .ListDetailList {
13041
+ overflow: auto;
13042
+ background: transparent;
13043
+ }
13044
+
13045
+ .ListDetail[data-layout='split'],
13046
+ .ListDetail[data-layout='drawer'],
13047
+ .ListDetail[data-layout='page'] {
13048
+ min-width: 0;
13049
+ }
13050
+
13051
+ .ListDetail[data-open] .ListDetailList {
13052
+ min-height: 0;
13053
+ }
13054
+
13055
+ .ListDetailDetail[data-layout='split'],
13056
+ .ListDetailDetail[data-layout='page'] {
13057
+ background: var(--sl-surface-raised);
13058
+ }
13059
+
13060
+ .ListDetailDetail[data-layout='drawer'] {
13061
+ background: transparent;
13062
+ }
13063
+
13064
+ .DrawerPopup .ListDetailHeader,
13065
+ .ListDetailDetail[data-layout='drawer'] .ListDetailBody {
13066
+ padding: 0;
13067
+ }
13068
+
13069
+ .ListDetailHeader {
13070
+ display: flex;
13071
+ align-items: center;
13072
+ gap: var(--sl-list-detail-header-gap);
13073
+ padding: var(--sl-list-detail-header-padding);
13074
+ flex: none;
13075
+ }
13076
+
13077
+ .ListDetailTitle {
13078
+ font-family: var(--sl-font-title-condense-font-family);
13079
+ font-size: var(--sl-font-title-condense-font-size);
13080
+ font-weight: var(--sl-font-title-condense-font-weight);
13081
+ line-height: var(--sl-font-title-condense-line-height);
13082
+ letter-spacing: var(--sl-font-title-condense-letter-spacing);
13083
+ margin: 0;
13084
+ flex: 1;
13085
+ min-width: 0;
13086
+ }
13087
+
13088
+ .ListDetailHeader .DrawerTitle {
13089
+ flex: 1;
13090
+ min-width: 0;
13091
+ }
13092
+
13093
+ .ListDetailActions {
13094
+ display: flex;
13095
+ align-items: center;
13096
+ gap: var(--sl-list-detail-header-gap);
13097
+ flex: none;
13098
+ }
13099
+
13100
+ .ListDetailBody {
13101
+ flex: 1;
13102
+ min-height: 0;
13103
+ overflow: auto;
13104
+ padding-inline: var(--sl-list-detail-header-padding);
13105
+ padding-block-end: var(--sl-list-detail-header-padding);
13106
+ }
13107
+
13108
+ .ListDetail[data-layout='drawer'] .ListDetailDetail {
13109
+ background: transparent;
13110
+ }
13111
+
13112
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13113
+ /* Splitter
13114
+ *
13115
+ * Two or more panels and a handle between them. Not a Base UI part. It follows the
13116
+ * window splitter pattern: the handle is a separator you drag or move with the arrow
13117
+ * keys. Each panel's size is --sl-splitter-panel-size, so a drag can update the line
13118
+ * without rendering the tree again. The parent gives the root its height.
13119
+ *
13120
+ * One panel has no size and fills what the others leave (the last panel, when every
13121
+ * panel has a size). Px and percent mix, so a workstation can pin its sides in pixels
13122
+ * while a list keeps a percent.
13123
+ *
13124
+ * Arrow keys move one key step, 5% of the splitter; Shift uses the larger step.
13125
+ * Home and End jump to that panel's min and max. Enter collapses a collapsible panel
13126
+ * and restores the size it had. Double-click resets to the default size. In RTL,
13127
+ * Left and Right swap. A panel collapsed to nothing is hidden, so its contents leave
13128
+ * the tab order.
13129
+ *
13130
+ * data-orientation is on the root, the panel and the handle. data-dragging is on the
13131
+ * root and the handle while the pointer is down. data-collapsed is on a collapsed
13132
+ * panel and on the handle that resizes it. data-disabled is on the handle. data-grip
13133
+ * draws the grip. data-fill marks the panel that takes the leftover space.
13134
+ *
13135
+ * The line is one stroke. The part you grab sits on the next panel's inline-start,
13136
+ * not centered, so it does not cover the previous panel's scrollbar. A fine pointer
13137
+ * gets a11y.min-target (24px). A coarse pointer gets the 44px touch target. The
13138
+ * focus ring is drawn on that grab area: a ring around the 1px line reads as a
13139
+ * second hairline. Collapse animates with duration.normal. A drag does not animate.
13140
+ * Reduced motion is the shared reset, which finishes every transition at once.
13141
+ */
13142
+
13143
+ .Splitter {
13144
+ display: flex;
13145
+ width: 100%;
13146
+ height: 100%;
13147
+ min-width: 0;
13148
+ min-height: 0;
13149
+ }
13150
+
13151
+ .Splitter[data-orientation='horizontal'] {
13152
+ flex-direction: row;
13153
+ }
13154
+
13155
+ .Splitter[data-orientation='vertical'] {
13156
+ flex-direction: column;
13157
+ }
13158
+
13159
+ .Splitter[data-dragging] .SplitterPanel {
13160
+ transition: none;
13161
+ }
13162
+
13163
+ .SplitterPanel {
13164
+ --sl-splitter-panel-size: auto;
13165
+ position: relative;
13166
+ box-sizing: border-box;
13167
+ min-width: 0;
13168
+ min-height: 0;
13169
+ overflow: hidden;
13170
+ flex: 0 0 var(--sl-splitter-panel-size);
13171
+ transition:
13172
+ flex-basis var(--sl-duration-normal) var(--sl-easing-default),
13173
+ width var(--sl-duration-normal) var(--sl-easing-default),
13174
+ height var(--sl-duration-normal) var(--sl-easing-default);
13175
+ }
13176
+
13177
+ .SplitterPanel[data-orientation='horizontal'] {
13178
+ width: var(--sl-splitter-panel-size);
13179
+ height: auto;
13180
+ }
13181
+
13182
+ .SplitterPanel[data-orientation='vertical'] {
13183
+ height: var(--sl-splitter-panel-size);
13184
+ width: auto;
13185
+ }
13186
+
13187
+ .SplitterPanel[data-orientation='horizontal'][data-fill]:not([data-collapsed]) {
13188
+ flex: 1 1 auto;
13189
+ width: auto;
13190
+ }
13191
+
13192
+ .SplitterPanel[data-orientation='vertical'][data-fill]:not([data-collapsed]) {
13193
+ flex: 1 1 auto;
13194
+ height: auto;
13195
+ }
13196
+
13197
+ /* A ScrollArea thumb still stacks above the grab area, for a bar that lives in the
13198
+ next panel, under the part of the hit area that crosses the line. */
13199
+ .SplitterPanel .ScrollAreaScrollbar {
13200
+ z-index: 2;
13201
+ }
13202
+
13203
+ .SplitterHandle {
13204
+ position: relative;
13205
+ flex: none;
13206
+ box-sizing: border-box;
13207
+ border: 0;
13208
+ padding: 0;
13209
+ background: transparent;
13210
+ touch-action: none;
13211
+ color: var(--sl-border-default);
13212
+ }
13213
+
13214
+ .SplitterHandle[data-orientation='horizontal'] {
13215
+ width: var(--sl-splitter-handle-size);
13216
+ height: auto;
13217
+ align-self: stretch;
13218
+ cursor: col-resize;
13219
+ }
13220
+
13221
+ .SplitterHandle[data-orientation='vertical'] {
13222
+ height: var(--sl-splitter-handle-size);
13223
+ width: auto;
13224
+ align-self: stretch;
13225
+ cursor: row-resize;
13226
+ }
13227
+
13228
+ .SplitterHandle::before,
13229
+ .SplitterHandle::after {
13230
+ content: '';
13231
+ position: absolute;
13232
+ }
13233
+
13234
+ .SplitterHandle::before {
13235
+ left: 50%;
13236
+ top: 50%;
13237
+ transform: translate(-50%, -50%);
13238
+ }
13239
+
13240
+ .SplitterHandle[data-orientation='horizontal']::before {
13241
+ width: var(--sl-splitter-handle-size);
13242
+ height: 100%;
13243
+ background: var(--sl-border-default);
13244
+ }
13245
+
13246
+ .SplitterHandle[data-orientation='vertical']::before {
13247
+ height: var(--sl-splitter-handle-size);
13248
+ width: 100%;
13249
+ background: var(--sl-border-default);
13250
+ }
13251
+
13252
+ /* The grab area starts on the line and extends into the next panel. The previous
13253
+ panel keeps its scrollbar, which sits on its inline-end, against this line. */
13254
+ .SplitterHandle[data-orientation='horizontal']::after {
13255
+ inset-inline-start: 0;
13256
+ top: 0;
13257
+ bottom: 0;
13258
+ width: var(--sl-a11y-min-target);
13259
+ z-index: 1;
13260
+ }
13261
+
13262
+ .SplitterHandle[data-orientation='vertical']::after {
13263
+ inset-block-start: 0;
13264
+ left: 0;
13265
+ right: 0;
13266
+ height: var(--sl-a11y-min-target);
13267
+ z-index: 1;
13268
+ }
13269
+
13270
+ @media (pointer: coarse) {
13271
+ .SplitterHandle[data-orientation='horizontal']::after {
13272
+ width: var(--sl-splitter-handle-hit-size);
13273
+ }
13274
+
13275
+ .SplitterHandle[data-orientation='vertical']::after {
13276
+ height: var(--sl-splitter-handle-hit-size);
13277
+ }
13278
+ }
13279
+
13280
+ .SplitterHandle:hover::before,
13281
+ .SplitterHandle[data-dragging]::before,
13282
+ .SplitterHandle[data-collapsed]::before {
13283
+ background: var(--sl-border-strong);
13284
+ }
13285
+
13286
+ /* The dot edge (45% to 50%) is the shape of the grip, not a size token. */
13287
+ /* The dots sit on the line, at the start of the grab area, not in its middle. */
13288
+ .SplitterHandle[data-orientation='horizontal'][data-grip]::after {
13289
+ background:
13290
+ radial-gradient(circle, var(--sl-border-strong) 45%, transparent 50%) inline-start calc(50% - var(--sl-splitter-grip-size) * 2) / var(--sl-splitter-grip-size) var(--sl-splitter-grip-size) no-repeat,
13291
+ radial-gradient(circle, var(--sl-border-strong) 45%, transparent 50%) inline-start center / var(--sl-splitter-grip-size) var(--sl-splitter-grip-size) no-repeat,
13292
+ radial-gradient(circle, var(--sl-border-strong) 45%, transparent 50%) inline-start calc(50% + var(--sl-splitter-grip-size) * 2) / var(--sl-splitter-grip-size) var(--sl-splitter-grip-size) no-repeat;
13293
+ }
13294
+
13295
+ .SplitterHandle[data-orientation='vertical'][data-grip]::after {
13296
+ background:
13297
+ radial-gradient(circle, var(--sl-border-strong) 45%, transparent 50%) calc(50% - var(--sl-splitter-grip-size) * 2) block-start / var(--sl-splitter-grip-size) var(--sl-splitter-grip-size) no-repeat,
13298
+ radial-gradient(circle, var(--sl-border-strong) 45%, transparent 50%) center block-start / var(--sl-splitter-grip-size) var(--sl-splitter-grip-size) no-repeat,
13299
+ radial-gradient(circle, var(--sl-border-strong) 45%, transparent 50%) calc(50% + var(--sl-splitter-grip-size) * 2) block-start / var(--sl-splitter-grip-size) var(--sl-splitter-grip-size) no-repeat;
13300
+ }
13301
+
13302
+ .SplitterHandle:focus {
13303
+ outline: none;
13304
+ }
13305
+
13306
+ .SplitterHandle:focus-visible::after {
13307
+ outline: var(--sl-focus-outline);
13308
+ outline-offset: var(--sl-focus-outline-offset);
13309
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
13310
+ }
13311
+
13312
+ .SplitterHandle[data-disabled] {
13313
+ cursor: not-allowed;
13314
+ }
13315
+
13316
+ .SplitterHandle[data-disabled]::before {
13317
+ background: var(--sl-border-default);
13318
+ }
13319
+
13320
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13321
+ /* EmptyState
13322
+ *
13323
+ * The block a page, pane, table, list or popup shows when it has nothing to show.
13324
+ * One look for every kind. data-kind only picks the media tone and, in the component,
13325
+ * the default icon and whether the block is announced. Sizes are empty.*
13326
+ * (tokens/semantic/empty.json). No border and no fill: the container provides those.
13327
+ *
13328
+ * The circle uses the subtle emphasis level (--sl-e-bg, --sl-e-fg), the same variables
13329
+ * Badge uses. data-status on the media recolors it. A parent data-color does too:
13330
+ * the subtle chrome pin skips this circle when a color scope is on an ancestor
13331
+ * (Badge keeps the pin). A brand pair re-points fill and text, not that chrome
13332
+ * scope. The circle stays chrome subtle inside a pair, the same as Badge, so a
13333
+ * pair does not get its own selector. High contrast and the vision themes come
13334
+ * with those variables. The title stays
13335
+ * text-primary and the description text-secondary: an error's title is not red,
13336
+ * because a sentence has to stay readable. Neutral kinds use the chrome palette,
13337
+ * which is what subtle resolves to when no status is set.
13338
+ *
13339
+ * Text is a whole style per size, not a font-size on its own. Compact is a table
13340
+ * row or a popup, so the title is subtitle-condense (bold, the row's size) and the
13341
+ * description is body-condense. Standard is a pane: title-condense, the section
13342
+ * heading, with body-base under it. Spacious is a page: title-magnify, the next
13343
+ * title up, still body-base so the sentence doesn't grow with the heading.
13344
+ * Unselected is the quiet pane beside a list, so it drops the circle, the icon is
13345
+ * text-tertiary, and the title steps down one tier: subtitle-minimize where the
13346
+ * others use a condense style (there is no title at minimize), and title-condense
13347
+ * where the others use title-magnify.
13348
+ *
13349
+ * Compact is a row (icon, text, actions) centered across the cell. Standard and
13350
+ * spacious are a column. They take margin-block: auto so a flex or grid column
13351
+ * centers them in the leftover space; in normal flow that margin is zero, so a
13352
+ * page that isn't a column doesn't grow a hole. There is no data-fill attribute.
13353
+ *
13354
+ * The icon for unselected is left_click: the pane is waiting for a choice in the
13355
+ * list beside it, which an empty inbox would not say.
13356
+ *
13357
+ * A popup's empty slot already pads a plain sentence (popup-empty). When the child
13358
+ * is an EmptyState, that padding drops so the two don't add. Menu.Empty has no
13359
+ * popup-empty padding of its own, so it needs nothing here.
13360
+ */
13361
+
13362
+ /* ============================================
13363
+ ROOT
13364
+ ============================================ */
13365
+
13366
+ .EmptyState {
13367
+ box-sizing: border-box;
13368
+ display: flex;
13369
+ flex-direction: column;
13370
+ align-items: center;
13371
+ justify-content: center;
13372
+ gap: var(--sl-empty-gap-standard);
13373
+ width: 100%;
13374
+ padding-block: var(--sl-empty-padding-block-standard);
13375
+ padding-inline: var(--sl-empty-padding-inline-standard);
13376
+ color: var(--sl-text-primary);
13377
+ text-align: center;
13378
+ }
13379
+
13380
+ /* ============================================
13381
+ MEDIA
13382
+ ============================================ */
13383
+
13384
+ .EmptyStateMedia {
13385
+ display: inline-flex;
13386
+ flex-shrink: 0;
13387
+ align-items: center;
13388
+ justify-content: center;
13389
+ width: var(--sl-empty-media-size-standard);
13390
+ height: var(--sl-empty-media-size-standard);
13391
+ border-radius: var(--sl-radius-pill);
13392
+ background: var(--sl-e-bg);
13393
+ color: var(--sl-e-fg);
13394
+ }
13395
+
13396
+ .EmptyStateMedia:not([data-custom]) .material-symbols-outlined,
13397
+ .EmptyStateMedia:not([data-custom]) svg {
13398
+ width: var(--sl-icon-size-magnify);
13399
+ height: var(--sl-icon-size-magnify);
13400
+ font-size: var(--sl-icon-size-magnify);
13401
+ line-height: 1;
13402
+ }
13403
+
13404
+ /* An illustration the app passed in. No circle and no tint. */
13405
+ .EmptyStateMedia[data-custom] {
13406
+ width: auto;
13407
+ height: auto;
13408
+ background: none;
13409
+ color: inherit;
13410
+ }
13411
+
13412
+ /* ============================================
13413
+ TEXT
13414
+ ============================================ */
13415
+
13416
+ .EmptyStateText {
13417
+ display: flex;
13418
+ flex-direction: column;
13419
+ align-items: center;
13420
+ gap: var(--sl-empty-text-gap-standard);
13421
+ min-width: 0;
13422
+ max-width: var(--sl-empty-description-max-width);
13423
+ }
13424
+
13425
+ .EmptyStateTitle {
13426
+ font-family: var(--sl-font-title-condense-font-family);
13427
+ font-size: var(--sl-font-title-condense-font-size);
13428
+ font-weight: var(--sl-font-title-condense-font-weight);
13429
+ line-height: var(--sl-font-title-condense-line-height);
13430
+ letter-spacing: var(--sl-font-title-condense-letter-spacing);
13431
+ margin: 0;
13432
+ max-width: 100%;
13433
+ color: var(--sl-text-primary);
13434
+ }
13435
+
13436
+ .EmptyStateDescription {
13437
+ font-family: var(--sl-font-body-base-font-family);
13438
+ font-size: var(--sl-font-body-base-font-size);
13439
+ font-weight: var(--sl-font-body-base-font-weight);
13440
+ line-height: var(--sl-font-body-base-line-height);
13441
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
13442
+ margin: 0;
13443
+ max-width: 100%;
13444
+ color: var(--sl-text-secondary);
13445
+ }
13446
+
13447
+ /* ============================================
13448
+ ACTIONS
13449
+ ============================================ */
13450
+
13451
+ .EmptyStateActions {
13452
+ display: flex;
13453
+ flex-wrap: wrap;
13454
+ align-items: center;
13455
+ justify-content: center;
13456
+ gap: var(--sl-empty-actions-gap);
13457
+ }
13458
+
13459
+ /* ============================================
13460
+ SIZES
13461
+ ============================================ */
13462
+
13463
+ .EmptyState[data-size='compact'] {
13464
+ flex-direction: row;
13465
+ flex-wrap: wrap;
13466
+ gap: var(--sl-empty-gap-compact);
13467
+ padding-block: var(--sl-empty-padding-block-compact);
13468
+ padding-inline: var(--sl-empty-padding-inline-compact);
13469
+ }
13470
+
13471
+ .EmptyState[data-size='compact'] .EmptyStateText {
13472
+ gap: var(--sl-empty-text-gap-compact);
13473
+ }
13474
+
13475
+ .EmptyState[data-size='compact'] .EmptyStateTitle {
13476
+ font-family: var(--sl-font-subtitle-condense-font-family);
13477
+ font-size: var(--sl-font-subtitle-condense-font-size);
13478
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
13479
+ line-height: var(--sl-font-subtitle-condense-line-height);
13480
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
13481
+ }
13482
+
13483
+ .EmptyState[data-size='compact'] .EmptyStateDescription {
13484
+ font-family: var(--sl-font-body-condense-font-family);
13485
+ font-size: var(--sl-font-body-condense-font-size);
13486
+ font-weight: var(--sl-font-body-condense-font-weight);
13487
+ line-height: var(--sl-font-body-condense-line-height);
13488
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
13489
+ }
13490
+
13491
+ /* Icon only. The tone stays on the glyph, so an error is still an error. */
13492
+ .EmptyState[data-size='compact'] .EmptyStateMedia {
13493
+ width: auto;
13494
+ height: auto;
13495
+ background: none;
13496
+ }
13497
+
13498
+ .EmptyState[data-size='compact'] .EmptyStateMedia:not([data-custom]) .material-symbols-outlined,
13499
+ .EmptyState[data-size='compact'] .EmptyStateMedia:not([data-custom]) svg {
13500
+ width: var(--sl-icon-size-condense);
13501
+ height: var(--sl-icon-size-condense);
13502
+ font-size: var(--sl-icon-size-condense);
13503
+ }
13504
+
13505
+ .EmptyState[data-size='spacious'] {
13506
+ gap: var(--sl-empty-gap-spacious);
13507
+ padding-block: var(--sl-empty-padding-block-spacious);
13508
+ padding-inline: var(--sl-empty-padding-inline-spacious);
13509
+ }
13510
+
13511
+ .EmptyState[data-size='spacious'] .EmptyStateText {
13512
+ gap: var(--sl-empty-text-gap-spacious);
13513
+ }
13514
+
13515
+ .EmptyState[data-size='spacious'] .EmptyStateTitle {
13516
+ font-family: var(--sl-font-title-magnify-font-family);
13517
+ font-size: var(--sl-font-title-magnify-font-size);
13518
+ font-weight: var(--sl-font-title-magnify-font-weight);
13519
+ line-height: var(--sl-font-title-magnify-line-height);
13520
+ letter-spacing: var(--sl-font-title-magnify-letter-spacing);
13521
+ }
13522
+
13523
+ .EmptyState[data-size='spacious'] .EmptyStateMedia {
13524
+ width: var(--sl-empty-media-size-spacious);
13525
+ height: var(--sl-empty-media-size-spacious);
13526
+ }
13527
+
13528
+ .EmptyState[data-size='spacious'] .EmptyStateMedia:not([data-custom]) .material-symbols-outlined,
13529
+ .EmptyState[data-size='spacious'] .EmptyStateMedia:not([data-custom]) svg {
13530
+ width: var(--sl-icon-size-maximize);
13531
+ height: var(--sl-icon-size-maximize);
13532
+ font-size: var(--sl-icon-size-maximize);
13533
+ }
13534
+
13535
+ /* ============================================
13536
+ PLACES
13537
+ ============================================ */
13538
+
13539
+ /* A flex or grid column centers the block in the space left over. */
13540
+ .EmptyState:is([data-size='standard'], [data-size='spacious']) {
13541
+ margin-block: auto;
13542
+ }
13543
+
13544
+ /* The detail pane before a row is picked. Quieter than the list beside it. */
13545
+ .EmptyState[data-kind='unselected'] .EmptyStateMedia {
13546
+ width: auto;
13547
+ height: auto;
13548
+ background: none;
13549
+ color: var(--sl-text-tertiary);
13550
+ }
13551
+
13552
+ .EmptyState[data-kind='unselected'][data-size='compact'] .EmptyStateTitle,
13553
+ .EmptyState[data-kind='unselected'][data-size='standard'] .EmptyStateTitle {
13554
+ font-family: var(--sl-font-subtitle-minimize-font-family);
13555
+ font-size: var(--sl-font-subtitle-minimize-font-size);
13556
+ font-weight: var(--sl-font-subtitle-minimize-font-weight);
13557
+ line-height: var(--sl-font-subtitle-minimize-line-height);
13558
+ letter-spacing: var(--sl-font-subtitle-minimize-letter-spacing);
13559
+ }
13560
+
13561
+ .EmptyState[data-kind='unselected'][data-size='spacious'] .EmptyStateTitle {
13562
+ font-family: var(--sl-font-title-condense-font-family);
13563
+ font-size: var(--sl-font-title-condense-font-size);
13564
+ font-weight: var(--sl-font-title-condense-font-weight);
13565
+ line-height: var(--sl-font-title-condense-line-height);
13566
+ letter-spacing: var(--sl-font-title-condense-letter-spacing);
13567
+ }
13568
+
13569
+ /* The popup slot pads a plain sentence. An EmptyState brings its own padding. */
13570
+ .ComboboxEmpty:has(> .EmptyState),
13571
+ .AutocompleteEmpty:has(> .EmptyState) {
13572
+ padding: 0;
13573
+ color: inherit;
13574
+ }
13575
+
13576
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13577
+ /* Table - Mojave Theme
13578
+ *
13579
+ * Base UI has no table, so this styles the native <table class="Table"> elements with the
13580
+ * table concept (tokens/semantic/table.json), the same tokens the AG Grid themes read: a small
13581
+ * hand-built table and a full grid look alike. Rows answer to aria-selected="true",
13582
+ * aria-current="true" (the row whose detail is open) or data-selected; cells take
13583
+ * data-align="end" for numbers.
13584
+ *
13585
+ * An empty body keeps the header and the column widths: one cell spanning the columns,
13586
+ * `<tr><td data-empty colSpan={n}><EmptyState size="compact" … /></td></tr>`. A cell with
13587
+ * only text still uses this rule's padding. A cell whose child is an EmptyState lets the
13588
+ * empty state pad itself. The empty row does not take the row hover.
13589
+ */
13590
+
13591
+ .Table {
13592
+ font-family: var(--sl-font-body-condense-font-family);
13593
+ font-size: var(--sl-font-body-condense-font-size);
13594
+ font-weight: var(--sl-font-body-condense-font-weight);
13595
+ line-height: var(--sl-font-body-condense-line-height);
13596
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
13597
+ box-sizing: border-box;
13598
+ width: 100%;
13599
+ border-collapse: separate;
13600
+ border-spacing: 0;
13601
+ background: var(--sl-table-background);
13602
+ color: var(--sl-table-color);
13603
+ border: var(--sl-stroke-default) solid var(--sl-table-border-color);
13604
+ border-radius: var(--sl-table-radius);
13605
+ overflow: hidden;
13606
+ font-variant-numeric: tabular-nums;
13607
+ }
13608
+
13609
+ .Table caption {
13610
+ font-family: var(--sl-font-body-condense-font-family);
13611
+ font-size: var(--sl-font-body-condense-font-size);
13612
+ font-weight: var(--sl-font-body-condense-font-weight);
13613
+ line-height: var(--sl-font-body-condense-line-height);
13614
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
13615
+ caption-side: bottom;
13616
+ padding-block: var(--sl-space-2);
13617
+ color: var(--sl-table-subtle-color);
13618
+ text-align: start;
13619
+ }
13620
+
13621
+ /* Header: the tray band, a little taller than the rows */
13622
+ .Table th {
13623
+ font-family: var(--sl-font-subtitle-condense-font-family);
13624
+ font-size: var(--sl-font-subtitle-condense-font-size);
13625
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
13626
+ line-height: var(--sl-font-subtitle-condense-line-height);
13627
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
13628
+ height: var(--sl-table-header-height);
13629
+ padding-block: 0;
13630
+ padding-inline: var(--sl-table-cell-padding-inline);
13631
+ background: var(--sl-table-header-background);
13632
+ color: var(--sl-table-header-color);
13633
+ text-align: start;
13634
+ vertical-align: middle;
13635
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-border-color);
13636
+ }
13637
+
13638
+ /* A header that sorts: aria-sort on the th */
13639
+ .Table th[aria-sort] {
13640
+ cursor: pointer;
13641
+ transition: background-color var(--sl-duration-fast) var(--sl-easing-default);
13642
+ }
13643
+
13644
+ .Table th[aria-sort]:hover {
13645
+ background: var(--sl-table-header-background-hover);
13646
+ }
13647
+
13648
+ /* Body cells */
13649
+ .Table td {
13650
+ height: var(--sl-table-row-height);
13651
+ padding-block: 0;
13652
+ padding-inline: var(--sl-table-cell-padding-inline);
13653
+ vertical-align: middle;
13654
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
13655
+ }
13656
+
13657
+ .Table tbody tr:last-child td,
13658
+ .Table tbody:last-child tr:last-child td {
13659
+ border-bottom: none;
13660
+ }
13661
+
13662
+ /* A row header (th in tbody) reads like a cell, in the header's weight */
13663
+ .Table tbody th {
13664
+ background: transparent;
13665
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
13666
+ }
13667
+
13668
+ /* Numbers and amounts: right-aligned so digits line up */
13669
+ .Table [data-align='end'] {
13670
+ text-align: end;
13671
+ }
13672
+
13673
+ .Table [data-align='center'] {
13674
+ text-align: center;
13675
+ }
13676
+
13677
+ /* Secondary text in a cell */
13678
+ .Table [data-subtle] {
13679
+ color: var(--sl-table-subtle-color);
13680
+ }
13681
+
13682
+ /* Hover and selection: the same tints as list items */
13683
+ @media (hover: hover) {
13684
+ .Table tbody tr:hover > * {
13685
+ background: var(--sl-table-row-hover);
13686
+ color: var(--sl-item-color-hover);
13687
+ }
13688
+ }
13689
+
13690
+ .Table tbody tr:is([aria-selected='true'], [data-selected]) > * {
13691
+ background: var(--sl-table-row-selected);
13692
+ color: var(--sl-item-color-selected);
13693
+ }
13694
+
13695
+ /* The open row keeps a fill, and a bar on the inline start so it is not only a color. */
13696
+ .Table tbody tr[aria-current='true'] > * {
13697
+ background: var(--sl-table-row-current);
13698
+ color: var(--sl-table-color);
13699
+ box-shadow: inset var(--sl-stroke-strong) 0 0 0 var(--sl-border-accent);
13700
+ }
13701
+
13702
+ [dir='rtl'] .Table tbody tr[aria-current='true'] > * {
13703
+ box-shadow: inset calc(var(--sl-stroke-strong) * -1) 0 0 0 var(--sl-border-accent);
13704
+ }
13705
+
13706
+ /* Footer: totals on the tray band */
13707
+ .Table tfoot td {
13708
+ font-family: var(--sl-font-subtitle-condense-font-family);
13709
+ font-size: var(--sl-font-subtitle-condense-font-size);
13710
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
13711
+ line-height: var(--sl-font-subtitle-condense-line-height);
13712
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
13713
+ background: var(--sl-table-header-background);
13714
+ border-top: var(--sl-stroke-default) solid var(--sl-table-border-color);
13715
+ border-bottom: none;
13716
+ }
13717
+
13718
+ /* A header that stays put while the body scrolls (the table's wrapper scrolls) */
13719
+ .Table[data-sticky-header] thead th {
13720
+ position: sticky;
13721
+ top: 0;
13722
+ z-index: var(--sl-z-index-docked);
13723
+ }
13724
+
13725
+ /* Empty state: one cell spanning the columns. Plain text keeps the old padding.
13726
+ An EmptyState brings its own, and its title stays the normal text color on hover. */
13727
+ .Table td[data-empty] {
13728
+ height: auto;
13729
+ padding-block: var(--sl-space-10);
13730
+ color: var(--sl-text-tertiary);
13731
+ text-align: center;
13732
+ }
13733
+
13734
+ .Table td[data-empty]:has(> .EmptyState) {
13735
+ padding: 0;
13736
+ color: inherit;
13737
+ }
13738
+
13739
+ .Table tbody tr:has(> td[data-empty]):hover > * {
13740
+ background: transparent;
13741
+ color: var(--sl-text-tertiary);
13742
+ }
13743
+
13744
+ .Table tbody tr:has(> td[data-empty] > .EmptyState):hover > * {
13745
+ color: inherit;
13746
+ }
13747
+
13748
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13749
+ /* Collection
13750
+ *
13751
+ * DataTable, DataList, the toolbar and the pagination, in one place so the two views
13752
+ * share the table concept. Sections: toolbar, table additions, groups, list, pagination, sizes.
13753
+ * Each section is its own file so the design system can name the part. This file brings them in.
13754
+ *
13755
+ * The selection bar replaces the trailing controls (filters, sort, clear, actions) and leaves
13756
+ * the tabs and the search where they are, so selecting rows does not grow the toolbar.
13757
+ */
13758
+
13759
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13760
+ /* Collection toolbar
13761
+ *
13762
+ * The wrap follows the toolbar's own width, not the window: a table in a narrow pane wraps
13763
+ * even when the page is wide. Search takes the full width first. Filters wrap under it.
13764
+ * A container query cannot read the width token, so the component also sets data-narrow.
13765
+ */
13766
+
13767
+ .CollectionToolbar {
13768
+ container-type: inline-size;
13769
+ display: flex;
13770
+ flex-direction: column;
13771
+ gap: var(--sl-collection-toolbar-gap);
13772
+ margin-block-end: var(--sl-collection-toolbar-gap);
13773
+ }
13774
+
13775
+ .CollectionToolbarMain,
13776
+ .CollectionToolbarTrailing,
13777
+ .CollectionSelectionBar,
13778
+ .CollectionSort {
13779
+ display: flex;
13780
+ flex-wrap: wrap;
13781
+ align-items: center;
13782
+ gap: var(--sl-collection-toolbar-gap);
13783
+ }
13784
+
13785
+ .CollectionSearch {
13786
+ display: flex;
13787
+ align-items: center;
13788
+ gap: var(--sl-collection-toolbar-gap);
13789
+ min-width: 0;
13790
+ }
13791
+
13792
+ .CollectionSearch .Input {
13793
+ min-width: 0;
13794
+ }
13795
+
13796
+ .CollectionToolbarActions {
13797
+ display: flex;
13798
+ flex-wrap: wrap;
13799
+ gap: var(--sl-collection-toolbar-gap);
13800
+ margin-inline-start: auto;
13801
+ }
13802
+
13803
+ /* The width token is measured in JS (data-narrow). A container query cannot read a custom property. */
13804
+ .CollectionToolbar[data-narrow] .CollectionSearch,
13805
+ .CollectionView[data-narrow] .CollectionSearch {
13806
+ flex-basis: 100%;
13807
+ }
13808
+
13809
+ .CollectionCount {
13810
+ font-family: var(--sl-font-body-condense-font-family);
13811
+ font-size: var(--sl-font-body-condense-font-size);
13812
+ font-weight: var(--sl-font-body-condense-font-weight);
13813
+ line-height: var(--sl-font-body-condense-line-height);
13814
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
13815
+ }
13816
+
13817
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13818
+ /* DataTable additions on top of .Table.
13819
+ *
13820
+ * Sort buttons fill the header cell and inherit its hover, so old aria-sort markup keeps
13821
+ * the hover it already had. The open row uses table.row-current, distinct from a selected row.
13822
+ * Loading dims the rows in place. Nothing here changes a plain .Table.
13823
+ */
13824
+
13825
+ .CollectionScroll {
13826
+ overflow: auto;
13827
+ max-width: 100%;
13828
+ }
13829
+
13830
+ .DataTable[data-size='sm'] {
13831
+ --sl-table-row-height: var(--sl-collection-row-height-sm);
13832
+ --sl-table-header-height: var(--sl-collection-header-height-sm);
13833
+ }
13834
+
13835
+ .DataTable[data-size='md'] {
13836
+ --sl-table-row-height: var(--sl-collection-row-height-md);
13837
+ --sl-table-header-height: var(--sl-collection-header-height-md);
13838
+ }
13839
+
13840
+ .Table th[aria-sort] > .TableSortButton {
13841
+ display: inline-flex;
13842
+ align-items: center;
13843
+ justify-content: inherit;
13844
+ gap: var(--sl-collection-toolbar-gap);
13845
+ width: 100%;
13846
+ height: 100%;
13847
+ margin: 0;
13848
+ padding: 0;
13849
+ border: 0;
13850
+ background: transparent;
13851
+ color: inherit;
13852
+ font: inherit;
13853
+ text-align: inherit;
13854
+ cursor: pointer;
13855
+ }
13856
+
13857
+ .TableSortIcon[data-state='none'] {
13858
+ visibility: hidden;
13859
+ }
13860
+
13861
+ .Table th[aria-sort]:hover .TableSortIcon[data-state='none'],
13862
+ .Table th[aria-sort]:focus-within .TableSortIcon[data-state='none'] {
13863
+ visibility: visible;
13864
+ }
13865
+
13866
+ .Table[data-sticky-row-header] tbody tr {
13867
+ --sl-row-fill: var(--sl-table-background);
13868
+ }
13869
+
13870
+ .Table[data-sticky-row-header] tbody tr:hover {
13871
+ --sl-row-fill: var(--sl-table-row-hover);
13872
+ }
13873
+
13874
+ .Table[data-sticky-row-header] tbody tr:is([aria-selected='true'], [data-selected]) {
13875
+ --sl-row-fill: var(--sl-table-row-selected);
13876
+ }
13877
+
13878
+ .Table[data-sticky-row-header] tbody tr[aria-current='true'] {
13879
+ --sl-row-fill: var(--sl-table-row-current);
13880
+ }
13881
+
13882
+ .Table[data-sticky-row-header] tbody th[scope='row'] {
13883
+ position: sticky;
13884
+ inset-inline-start: 0;
13885
+ z-index: var(--sl-z-index-docked);
13886
+ background: var(--sl-row-fill);
13887
+ }
13888
+
13889
+ .TableSortButton:focus-visible,
13890
+ .CollectionGroupButton:focus-visible,
13891
+ .CollectionRowButton:focus-visible {
13892
+ outline: var(--sl-focus-outline);
13893
+ outline-offset: var(--sl-focus-outline-offset);
13894
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
13895
+ }
13896
+
13897
+ .Table tr[data-group] th {
13898
+ background: var(--sl-table-group-header-background);
13899
+ color: var(--sl-table-header-color);
13900
+ }
13901
+
13902
+ .CollectionGroupButton,
13903
+ .CollectionRowButton {
13904
+ margin: 0;
13905
+ padding: 0;
13906
+ border: 0;
13907
+ background: transparent;
13908
+ color: inherit;
13909
+ font: inherit;
13910
+ text-align: inherit;
13911
+ cursor: pointer;
13912
+ }
13913
+
13914
+ .DataTable[data-loading] tbody {
13915
+ opacity: var(--sl-item-opacity-disabled);
13916
+ transition: opacity var(--sl-duration-fast) var(--sl-easing-default);
13917
+ }
13918
+
13919
+ .CollectionSelectColumn {
13920
+ width: var(--sl-collection-selection-column-width);
13921
+ }
13922
+
13923
+ .Table th[data-width='min'],
13924
+ .Table td[data-width='min'] {
13925
+ width: min-content;
13926
+ white-space: nowrap;
13927
+ }
13928
+
13929
+ .CollectionStatus {
13930
+ font-family: var(--sl-font-body-condense-font-family);
13931
+ font-size: var(--sl-font-body-condense-font-size);
13932
+ font-weight: var(--sl-font-body-condense-font-weight);
13933
+ line-height: var(--sl-font-body-condense-line-height);
13934
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
13935
+ color: var(--sl-table-subtle-color);
13936
+ }
13937
+
13938
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13939
+ /* DataList
13940
+ *
13941
+ * The same rows as the table, in one container with the table's borders, hover, selected
13942
+ * and current states. Not a stack of floating cards: the two views should read as one family.
13943
+ * variant=cards adds the surface radius and a gap when a queue should read as separate items.
13944
+ */
13945
+
13946
+ .DataList {
13947
+ font-family: var(--sl-font-body-condense-font-family);
13948
+ font-size: var(--sl-font-body-condense-font-size);
13949
+ font-weight: var(--sl-font-body-condense-font-weight);
13950
+ line-height: var(--sl-font-body-condense-line-height);
13951
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
13952
+ color: var(--sl-table-color);
13953
+ }
13954
+
13955
+ .DataList ul {
13956
+ margin: 0;
13957
+ padding: 0;
13958
+ list-style: none;
13959
+ background: var(--sl-table-background);
13960
+ border: var(--sl-stroke-default) solid var(--sl-table-border-color);
13961
+ border-radius: var(--sl-table-radius);
13962
+ }
13963
+
13964
+ .DataList li {
13965
+ display: flex;
13966
+ align-items: flex-start;
13967
+ gap: var(--sl-collection-list-row-gap);
13968
+ padding-block: var(--sl-collection-list-row-padding-block);
13969
+ padding-inline: var(--sl-table-cell-padding-inline);
13970
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
13971
+ }
13972
+
13973
+ .DataList li:last-child {
13974
+ border-bottom: none;
13975
+ }
13976
+
13977
+ .DataList[data-size='md'] li {
13978
+ padding-block: var(--sl-collection-list-row-padding-block);
13979
+ min-height: var(--sl-collection-row-height-md);
13980
+ }
13981
+
13982
+ .DataList li[data-selected] {
13983
+ background: var(--sl-table-row-selected);
13984
+ color: var(--sl-table-color);
13985
+ }
13986
+
13987
+ .DataList li[aria-current='true'] {
13988
+ background: var(--sl-table-row-current);
13989
+ color: var(--sl-table-color);
13990
+ box-shadow: inset var(--sl-stroke-strong) 0 0 0 var(--sl-border-accent);
13991
+ }
13992
+
13993
+ @media (hover: hover) {
13994
+ .DataList li:hover:not([data-selected], [aria-current='true']) {
13995
+ background: var(--sl-table-row-hover);
13996
+ color: var(--sl-table-color);
13997
+ }
13998
+ }
13999
+
14000
+ .DataListPrimary {
14001
+ font-family: var(--sl-font-subtitle-condense-font-family);
14002
+ font-size: var(--sl-font-subtitle-condense-font-size);
14003
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
14004
+ line-height: var(--sl-font-subtitle-condense-line-height);
14005
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
14006
+ }
14007
+
14008
+ .DataListSecondary,
14009
+ .DataListMeta,
14010
+ .DataListSummary {
14011
+ font-family: var(--sl-font-body-condense-font-family);
14012
+ font-size: var(--sl-font-body-condense-font-size);
14013
+ font-weight: var(--sl-font-body-condense-font-weight);
14014
+ line-height: var(--sl-font-body-condense-line-height);
14015
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
14016
+ color: var(--sl-table-subtle-color);
14017
+ }
14018
+
14019
+ .DataListBody {
14020
+ display: flex;
14021
+ flex: 1;
14022
+ flex-direction: column;
14023
+ gap: var(--sl-space-1);
14024
+ min-width: 0;
14025
+ }
14026
+
14027
+ .DataListMeta {
14028
+ display: flex;
14029
+ flex-wrap: wrap;
14030
+ gap: var(--sl-collection-list-row-gap);
14031
+ }
14032
+
14033
+ .DataListAmount {
14034
+ margin-inline-start: auto;
14035
+ font-variant-numeric: tabular-nums;
14036
+ }
14037
+
14038
+ .DataListGroup {
14039
+ background: var(--sl-table-group-header-background);
14040
+ color: var(--sl-table-header-color);
14041
+ }
14042
+
14043
+ .DataList[data-variant='cards'] ul {
14044
+ display: flex;
14045
+ flex-direction: column;
14046
+ gap: var(--sl-collection-list-row-gap);
14047
+ background: transparent;
14048
+ border: 0;
14049
+ }
14050
+
14051
+ .DataList[data-variant='cards'] li {
14052
+ background: var(--sl-table-background);
14053
+ border: var(--sl-stroke-default) solid var(--sl-table-border-color);
14054
+ border-radius: var(--sl-table-radius);
14055
+ }
14056
+
14057
+ .DataList[data-loading] ul {
14058
+ opacity: var(--sl-item-opacity-disabled);
14059
+ transition: opacity var(--sl-duration-fast) var(--sl-easing-default);
14060
+ }
14061
+
14062
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
14063
+ /* Pagination
14064
+ *
14065
+ * Not tied to a collection. Anything with a page, a page count and a total can use it.
14066
+ * Previous and Next are quiet buttons. The count reads "1–25 of 312".
14067
+ */
14068
+
14069
+ .CollectionPagination {
14070
+ display: flex;
14071
+ flex-wrap: wrap;
14072
+ align-items: center;
14073
+ gap: var(--sl-collection-toolbar-gap);
14074
+ margin-block-start: var(--sl-collection-toolbar-gap);
14075
+ color: var(--sl-table-subtle-color);
14076
+ }
14077
+
14078
+ .CollectionPagination p {
14079
+ font-family: var(--sl-font-body-condense-font-family);
14080
+ font-size: var(--sl-font-body-condense-font-size);
14081
+ font-weight: var(--sl-font-body-condense-font-weight);
14082
+ line-height: var(--sl-font-body-condense-line-height);
14083
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
14084
+ margin: 0;
14085
+ }
14086
+
14087
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
14088
+ /* EditableList
14089
+ *
14090
+ * One table at every width, so a field is not submitted twice. Under the stack width each
14091
+ * field shows its own label, so the lost header association does not matter: the input's
14092
+ * name comes from that label, not from the column header.
14093
+ *
14094
+ * Move up / Move down would be quiet buttons in the last cell, ahead of any future drag handle.
14095
+ */
14096
+
14097
+ .EditableList {
14098
+ container-type: inline-size;
14099
+ }
14100
+
14101
+ .EditableListAdd,
14102
+ .EditableListError,
14103
+ .EditableListBalance {
14104
+ margin-block-start: var(--sl-collection-toolbar-gap);
14105
+ }
14106
+
14107
+ .EditableListFieldLabel {
14108
+ display: none;
14109
+ }
14110
+
14111
+ .EditableListBalance {
14112
+ font-family: var(--sl-font-body-condense-font-family);
14113
+ font-size: var(--sl-font-body-condense-font-size);
14114
+ font-weight: var(--sl-font-body-condense-font-weight);
14115
+ line-height: var(--sl-font-body-condense-line-height);
14116
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
14117
+ padding: var(--sl-space-2) var(--sl-space-3);
14118
+ border-radius: var(--sl-radius-control);
14119
+ }
14120
+
14121
+ .EditableListBalance[data-color] {
14122
+ background: var(--sl-scope-soft);
14123
+ color: var(--sl-scope-on-soft);
14124
+ }
14125
+
14126
+ .EditableListStackedTitle {
14127
+ display: none;
14128
+ font-family: var(--sl-font-subtitle-condense-font-family);
14129
+ font-size: var(--sl-font-subtitle-condense-font-size);
14130
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
14131
+ line-height: var(--sl-font-subtitle-condense-line-height);
14132
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
14133
+ }
14134
+
14135
+ .EditableList[data-stacked] .EditableListStackedTitle {
14136
+ display: block;
14137
+ }
14138
+
14139
+ .EditableListRowLead {
14140
+ width: 0;
14141
+ padding: 0;
14142
+ border: 0;
14143
+ }
14144
+
14145
+ .EditableList td .Input,
14146
+ .EditableList td input,
14147
+ .EditableList td select {
14148
+ width: 100%;
14149
+ }
14150
+
14151
+ /* The width token is measured in JS. data-stacked is that measurement. */
14152
+ .EditableList[data-stacked] {
14153
+ .EditableListTable,
14154
+ .EditableListTable thead,
14155
+ .EditableListTable tbody,
14156
+ .EditableListTable tr,
14157
+ .EditableListTable td {
14158
+ display: block;
14159
+ width: 100%;
14160
+ height: auto;
14161
+ }
14162
+
14163
+ .EditableListTable thead {
14164
+ position: absolute;
14165
+ width: var(--sl-space-px);
14166
+ height: var(--sl-space-px);
14167
+ overflow: hidden;
14168
+ clip: rect(0, 0, 0, 0);
14169
+ }
14170
+
14171
+ .EditableListTable tr {
14172
+ padding-block: var(--sl-collection-list-row-padding-block);
14173
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
14174
+ }
14175
+
14176
+ .EditableListFieldLabel {
14177
+ display: block;
14178
+ font-family: var(--sl-font-subtitle-condense-font-family);
14179
+ font-size: var(--sl-font-subtitle-condense-font-size);
14180
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
14181
+ line-height: var(--sl-font-subtitle-condense-line-height);
14182
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
14183
+ }
14184
+ }