@scattered-light/loomiere-base-ui 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 (100) hide show
  1. package/README.md +135 -5
  2. package/dist/chunk-JUUPOOQQ.js +3723 -0
  3. package/dist/chunk-JUUPOOQQ.js.map +1 -0
  4. package/dist/chunk-M7KJASGK.js +802 -0
  5. package/dist/chunk-M7KJASGK.js.map +1 -0
  6. package/dist/chunk-Y2CPBMFJ.js +147 -0
  7. package/dist/chunk-Y2CPBMFJ.js.map +1 -0
  8. package/dist/custom/collection/index.d.ts +534 -0
  9. package/dist/custom/collection/index.js +1471 -0
  10. package/dist/custom/collection/index.js.map +1 -0
  11. package/dist/custom/index.d.ts +5 -0
  12. package/dist/custom/index.js +4 -0
  13. package/dist/custom/index.js.map +1 -0
  14. package/dist/design-system/components/Badge/README.md +35 -0
  15. package/dist/design-system/components/Badge/preview.html +19 -0
  16. package/dist/design-system/components/Collection/README.md +14 -0
  17. package/dist/design-system/components/CollectionPagination/README.md +15 -0
  18. package/dist/design-system/components/CollectionToolbar/README.md +24 -0
  19. package/dist/design-system/components/DataList/README.md +39 -0
  20. package/dist/design-system/components/DataList/preview.html +475 -0
  21. package/dist/design-system/components/DataTable/README.md +41 -0
  22. package/dist/design-system/components/DataTable/preview.html +475 -0
  23. package/dist/design-system/components/DatePicker/README.md +55 -0
  24. package/dist/design-system/components/DatePicker/preview.html +475 -0
  25. package/dist/design-system/components/EditableList/README.md +33 -0
  26. package/dist/design-system/components/EditableList/preview.html +475 -0
  27. package/dist/design-system/components/EmptyState/README.md +60 -0
  28. package/dist/design-system/components/EmptyState/preview.html +475 -0
  29. package/dist/design-system/components/ListDetail/README.md +43 -0
  30. package/dist/design-system/components/ListDetail/preview.html +475 -0
  31. package/dist/design-system/components/MoneyField/README.md +52 -0
  32. package/dist/design-system/components/MoneyField/preview.html +475 -0
  33. package/dist/design-system/components/Splitter/README.md +42 -0
  34. package/dist/design-system/components/Splitter/preview.html +475 -0
  35. package/dist/design-system/components/Table/README.md +2 -1
  36. package/dist/design-system/components/Table/preview.html +1 -1
  37. package/dist/design-system/components/bundle.js +7 -5
  38. package/dist/design-system/components/index.d.ts +3 -21
  39. package/dist/design-system/components/styles.css +2266 -186
  40. package/dist/index-ChJXlxzq.d.ts +809 -0
  41. package/dist/index.d.ts +3 -21
  42. package/dist/index.js +176 -891
  43. package/dist/index.js.map +1 -1
  44. package/dist/styles/components/Accordion.css +1 -1
  45. package/dist/styles/components/AlertDialog.css +1 -1
  46. package/dist/styles/components/Autocomplete.css +1 -1
  47. package/dist/styles/components/Avatar.css +1 -1
  48. package/dist/styles/components/Button.css +1 -1
  49. package/dist/styles/components/Checkbox.css +1 -1
  50. package/dist/styles/components/CheckboxGroup.css +1 -1
  51. package/dist/styles/components/Collapsible.css +1 -1
  52. package/dist/styles/components/Combobox.css +1 -1
  53. package/dist/styles/components/ContextMenu.css +1 -1
  54. package/dist/styles/components/Dialog.css +1 -1
  55. package/dist/styles/components/Drawer.css +1 -1
  56. package/dist/styles/components/Field.css +1 -1
  57. package/dist/styles/components/Fieldset.css +1 -1
  58. package/dist/styles/components/Form.css +1 -1
  59. package/dist/styles/components/Input.css +1 -1
  60. package/dist/styles/components/Menu.css +1 -1
  61. package/dist/styles/components/Menubar.css +1 -1
  62. package/dist/styles/components/Meter.css +1 -1
  63. package/dist/styles/components/NavigationMenu.css +1 -1
  64. package/dist/styles/components/NumberField.css +1 -1
  65. package/dist/styles/components/OTPField.css +1 -1
  66. package/dist/styles/components/Popover.css +1 -1
  67. package/dist/styles/components/PreviewCard.css +1 -1
  68. package/dist/styles/components/Progress.css +1 -1
  69. package/dist/styles/components/Radio.css +1 -1
  70. package/dist/styles/components/ScrollArea.css +1 -1
  71. package/dist/styles/components/Select.css +1 -1
  72. package/dist/styles/components/Separator.css +1 -1
  73. package/dist/styles/components/Slider.css +1 -1
  74. package/dist/styles/components/Switch.css +1 -1
  75. package/dist/styles/components/Tabs.css +1 -1
  76. package/dist/styles/components/Toast.css +1 -1
  77. package/dist/styles/components/Toggle.css +1 -1
  78. package/dist/styles/components/ToggleGroup.css +1 -1
  79. package/dist/styles/components/Toolbar.css +1 -1
  80. package/dist/styles/components/Tooltip.css +1 -1
  81. package/dist/styles/custom/Badge.css +104 -0
  82. package/dist/styles/custom/Collection.css +15 -0
  83. package/dist/styles/custom/CollectionPagination.css +24 -0
  84. package/dist/styles/custom/CollectionToolbar.css +57 -0
  85. package/dist/styles/custom/DataList.css +123 -0
  86. package/dist/styles/custom/DataTable.css +120 -0
  87. package/dist/styles/custom/DatePicker.css +572 -0
  88. package/dist/styles/custom/EditableList.css +98 -0
  89. package/dist/styles/custom/EmptyState.css +255 -0
  90. package/dist/styles/custom/ListDetail.css +126 -0
  91. package/dist/styles/custom/MoneyField.css +344 -0
  92. package/dist/styles/custom/Splitter.css +207 -0
  93. package/dist/styles/{components → custom}/Table.css +31 -4
  94. package/dist/styles/index.css +12 -2
  95. package/dist/styles/reset/accessibility.css +1 -1
  96. package/dist/styles/reset/reset-accessibility.css +1 -1
  97. package/dist/styles/reset/reset-tailwind.css +1 -1
  98. package/dist/styles/reset/reset.css +1 -1
  99. package/dist/styles/tailwind.css +12 -2
  100. package/package.json +36 -8
@@ -1,5 +1,5 @@
1
1
  @import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,400,0..1,0');
2
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3
3
  /* Loomiere for Base UI: component styles. Brand-free: every value is a --sl- variable from a
4
4
  Loomiere theme. Load the theme first:
5
5
  @import '<your theme>/tokens.css';
@@ -9,7 +9,7 @@
9
9
  /* Document defaults, in the reset layer so any unlayered rule wins over them, and so layered
10
10
  frameworks (Chakra's recipes, Tailwind's utilities) are not undone by them. */
11
11
  @layer reset {
12
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
12
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
13
13
  /* CSS Reset - Mojave Theme */
14
14
 
15
15
  /* ============================================
@@ -453,7 +453,7 @@ hr {
453
453
  }
454
454
  }
455
455
  @layer reset {
456
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
456
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
457
457
  /* Accessibility — base rules (no theme color dependencies). Theme-specific focus/invalid: accessibility-theme.css */
458
458
 
459
459
  /* Remove default focus; keyboard focus styled in accessibility-theme.css */
@@ -566,7 +566,7 @@ main:focus {
566
566
 
567
567
  }
568
568
  @layer reset {
569
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
569
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
570
570
  /* Focus, invalid, contrast — requires theme tokens (after theme-accessibility.css). */
571
571
 
572
572
  :focus-visible {
@@ -634,7 +634,7 @@ button,
634
634
 
635
635
  }
636
636
  /* Component styles */
637
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
637
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
638
638
  /* Accordion - Mojave Theme
639
639
  *
640
640
  * No component tokens. Hover, press, chevron, divider and motion are the disclosure
@@ -755,7 +755,7 @@ button,
755
755
  overflow: hidden;
756
756
  }
757
757
 
758
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
758
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
759
759
  /* Alert Dialog - Mojave Theme
760
760
  *
761
761
  * No component tokens and no rules of its own. An alert dialog looks exactly like a
@@ -764,7 +764,7 @@ button,
764
764
  * cancel quiet, and a destructive one bold with data-color="error".
765
765
  */
766
766
 
767
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
767
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
768
768
  /* Autocomplete - Mojave Theme
769
769
  *
770
770
  * No component tokens. The input is Input (Input.css), the clear button is an icon
@@ -966,7 +966,7 @@ button,
966
966
  (reset-accessibility.css).
967
967
  ============================================ */
968
968
 
969
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
969
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
970
970
  /* Avatar - Mojave Theme
971
971
  *
972
972
  * A round picture with a ring in the page color, so avatars in a group cut out of each other in
@@ -1074,7 +1074,7 @@ button,
1074
1074
  }
1075
1075
  }
1076
1076
 
1077
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
1077
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
1078
1078
  /* Button - Mojave Theme
1079
1079
  *
1080
1080
  * Colors are the brand's emphasis levels, sizes are control.*, text is the trigger
@@ -1224,7 +1224,7 @@ button,
1224
1224
  font-size: var(--sl-icon-size-maximize);
1225
1225
  }
1226
1226
 
1227
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
1227
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
1228
1228
  /* Checkbox - Mojave Theme
1229
1229
  * Sizes follow the label: the box is the icon size one tier above the label's text
1230
1230
  * tier (like a button's icon) and the check mark one tier below it.
@@ -1381,7 +1381,7 @@ button,
1381
1381
  border-radius: var(--sl-radius-pill);
1382
1382
  }
1383
1383
 
1384
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
1384
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
1385
1385
  /* Checkbox Group - Mojave Theme */
1386
1386
 
1387
1387
  /* Each checkbox row is already a full tap target tall, so the rows sit close. */
@@ -1397,7 +1397,7 @@ button,
1397
1397
  pointer-events: none;
1398
1398
  }
1399
1399
 
1400
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
1400
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
1401
1401
  /* Collapsible - Mojave Theme
1402
1402
  *
1403
1403
  * No component tokens. Hover, press, chevron and motion are the disclosure concept
@@ -1513,7 +1513,7 @@ button,
1513
1513
  background: var(--sl-surface-raised);
1514
1514
  }
1515
1515
 
1516
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
1516
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
1517
1517
  /* Combobox - Mojave Theme
1518
1518
  *
1519
1519
  * No component tokens. The input is Input (Input.css); the chips box is a field; the
@@ -1998,7 +1998,7 @@ button,
1998
1998
  color: var(--sl-text-tertiary);
1999
1999
  }
2000
2000
 
2001
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2001
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2002
2002
  /* Context Menu - Mojave Theme
2003
2003
  *
2004
2004
  * 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
@@ -2167,7 +2167,7 @@ button,
2167
2167
  stroke-width: var(--sl-stroke-default);
2168
2168
  }
2169
2169
 
2170
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2170
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2171
2171
  /* Dialog and Alert dialog - Mojave Theme
2172
2172
  *
2173
2173
  * Both are centered modals built from the modal concept (tokens/semantic/modal.json):
@@ -2313,7 +2313,7 @@ button,
2313
2313
  margin-top: var(--sl-modal-actions-spacing);
2314
2314
  }
2315
2315
 
2316
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2316
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2317
2317
  /* Drawer - a panel that slides in from an edge and can be swiped away.
2318
2318
  The surface, scrim, heading and motion are the modal concept's (--sl-modal-*), so a
2319
2319
  drawer reads as a dialog's sibling; only its size and grab bar are its own
@@ -2440,7 +2440,7 @@ button,
2440
2440
  color: var(--sl-modal-description-color);
2441
2441
  }
2442
2442
 
2443
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2443
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2444
2444
  /* Field - Mojave Theme
2445
2445
  *
2446
2446
  * Label, control, description and error. No component tokens: spacing is the field
@@ -2501,7 +2501,7 @@ textarea.FieldControl {
2501
2501
  height: auto;
2502
2502
  }
2503
2503
 
2504
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2504
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2505
2505
  /* Fieldset - Mojave Theme
2506
2506
  *
2507
2507
  * No component tokens: a titled group of fields, spaced by the stack gaps, with
@@ -2543,7 +2543,7 @@ textarea.FieldControl {
2543
2543
  color: var(--sl-text-secondary);
2544
2544
  }
2545
2545
 
2546
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2546
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2547
2547
  /* Form - Mojave Theme
2548
2548
  *
2549
2549
  * No component tokens: fields stack with the large block space, and the action
@@ -2563,7 +2563,7 @@ textarea.FieldControl {
2563
2563
  margin-top: var(--sl-space-block-md);
2564
2564
  }
2565
2565
 
2566
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2566
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2567
2567
  /* Input - Mojave Theme
2568
2568
  *
2569
2569
  * No component tokens: the look is the field concept (tokens/semantic/field.json),
@@ -2700,7 +2700,7 @@ textarea.FieldControl {
2700
2700
  padding-inline: var(--sl-control-padding-inline-lg);
2701
2701
  }
2702
2702
 
2703
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2703
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2704
2704
  /* Menu - Mojave Theme
2705
2705
  *
2706
2706
  * No component tokens. The trigger is a Button. The popup is the popup concept, rows are item rows at the
@@ -2849,7 +2849,7 @@ textarea.FieldControl {
2849
2849
  color: var(--sl-text-tertiary);
2850
2850
  }
2851
2851
 
2852
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
2852
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
2853
2853
  /* Menubar - Mojave Theme
2854
2854
  *
2855
2855
  * No component tokens. A row of quiet triggers, each opening a menu. The popup is the popup concept, rows are item rows at the
@@ -3042,7 +3042,7 @@ textarea.FieldControl {
3042
3042
  color: var(--sl-text-tertiary);
3043
3043
  }
3044
3044
 
3045
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3045
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3046
3046
  /* Meter - Mojave Theme
3047
3047
  *
3048
3048
  * A gauge (tokens/semantic/gauge.json). The fill is the solid color of the scope around it:
@@ -3105,7 +3105,7 @@ textarea.FieldControl {
3105
3105
  height: var(--sl-gauge-height-lg);
3106
3106
  }
3107
3107
 
3108
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3108
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3109
3109
  /* Navigation Menu - Mojave Theme
3110
3110
  *
3111
3111
  * The strip is the bar concept, the panel is the popup concept and each link is an item
@@ -3525,7 +3525,7 @@ textarea.FieldControl {
3525
3525
  width: 100%;
3526
3526
  }
3527
3527
 
3528
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3528
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3529
3529
  /* Number Field - Mojave Theme
3530
3530
  *
3531
3531
  * No component tokens. The input is Input (Input.css) and the label, description and
@@ -3616,7 +3616,7 @@ textarea.FieldControl {
3616
3616
  user-select: none;
3617
3617
  }
3618
3618
 
3619
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3619
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3620
3620
  /* OTP Field - Mojave Theme
3621
3621
  *
3622
3622
  * One-time code entry: a row of single-character inputs. Each slot is the same control as Input
@@ -3679,7 +3679,7 @@ textarea.FieldControl {
3679
3679
  letter-spacing: var(--sl-font-body-magnify-letter-spacing);
3680
3680
  }
3681
3681
 
3682
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3682
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3683
3683
  /* Popover - Mojave Theme */
3684
3684
 
3685
3685
  /* ============================================
@@ -3844,7 +3844,7 @@ textarea.FieldControl {
3844
3844
  fill: var(--sl-popup-arrow-stroke);
3845
3845
  }
3846
3846
 
3847
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3847
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3848
3848
  /* Preview Card - Mojave Theme
3849
3849
  *
3850
3850
  * The popup concept (surface, arrow, motion) with a title-magnify title and condense
@@ -3961,7 +3961,7 @@ textarea.FieldControl {
3961
3961
  fill: var(--sl-popup-arrow-stroke);
3962
3962
  }
3963
3963
 
3964
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
3964
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
3965
3965
  /* Progress - Mojave Theme
3966
3966
  *
3967
3967
  * A gauge (tokens/semantic/gauge.json), the same bar as Meter. The fill is the solid color of
@@ -4038,7 +4038,7 @@ textarea.FieldControl {
4038
4038
  height: var(--sl-gauge-height-lg);
4039
4039
  }
4040
4040
 
4041
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4041
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
4042
4042
  /* Radio - Mojave Theme
4043
4043
  * Same box as Checkbox, always round. Sizes follow the label the same way, and the
4044
4044
  * dot is a share of the circle (check.dot-scale).
@@ -4190,7 +4190,7 @@ textarea.FieldControl {
4190
4190
  gap: var(--sl-gap-stack-sm);
4191
4191
  }
4192
4192
 
4193
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4193
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
4194
4194
  /* Scroll Area - Mojave Theme
4195
4195
  *
4196
4196
  * The scrollbar is the content scrollbar (content.scrollbar-*): a track that stays clear until
@@ -4272,7 +4272,7 @@ textarea.FieldControl {
4272
4272
  background: transparent;
4273
4273
  }
4274
4274
 
4275
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4275
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
4276
4276
  /* Select - Mojave Theme
4277
4277
  *
4278
4278
  * The trigger is a field (the field pattern, control sizes, the base text style); the
@@ -4557,7 +4557,7 @@ textarea.FieldControl {
4557
4557
  stroke-width: var(--sl-stroke-default);
4558
4558
  }
4559
4559
 
4560
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4560
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
4561
4561
  /* Separator - Mojave Theme
4562
4562
  *
4563
4563
  * A hairline in the everyday divider color (border.default), one stroke thick, with a step of
@@ -4585,7 +4585,7 @@ textarea.FieldControl {
4585
4585
  margin-inline: var(--sl-space-4);
4586
4586
  }
4587
4587
 
4588
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4588
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
4589
4589
  /* Slider - Mojave Theme
4590
4590
  *
4591
4591
  * A slider is a gauge you can drag: the track, fill and label row are gauge.* (the same bar as
@@ -4751,7 +4751,7 @@ textarea.FieldControl {
4751
4751
  transform: translate(-50%, 50%);
4752
4752
  }
4753
4753
 
4754
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4754
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
4755
4755
  /* Switch - Mojave Theme
4756
4756
  * Switch keeps its track sizes. The thumb, its travel and the ON/OFF text are
4757
4757
  * worked out from them: the thumb fills the track's height inside the padding,
@@ -4917,152 +4917,7 @@ textarea.FieldControl {
4917
4917
  color: var(--sl-text-disabled);
4918
4918
  }
4919
4919
 
4920
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4921
- /* Table - Mojave Theme
4922
- *
4923
- * Base UI has no table, so this styles the native <table class="Table"> elements with the
4924
- * table concept (tokens/semantic/table.json), the same tokens the AG Grid themes read: a small
4925
- * hand-built table and a full grid look alike. Rows answer to aria-selected="true" (or
4926
- * data-selected) for selection; cells take data-align="end" for numbers.
4927
- */
4928
-
4929
- .Table {
4930
- font-family: var(--sl-font-body-condense-font-family);
4931
- font-size: var(--sl-font-body-condense-font-size);
4932
- font-weight: var(--sl-font-body-condense-font-weight);
4933
- line-height: var(--sl-font-body-condense-line-height);
4934
- letter-spacing: var(--sl-font-body-condense-letter-spacing);
4935
- box-sizing: border-box;
4936
- width: 100%;
4937
- border-collapse: separate;
4938
- border-spacing: 0;
4939
- background: var(--sl-table-background);
4940
- color: var(--sl-table-color);
4941
- border: var(--sl-stroke-default) solid var(--sl-table-border-color);
4942
- border-radius: var(--sl-table-radius);
4943
- overflow: hidden;
4944
- font-variant-numeric: tabular-nums;
4945
- }
4946
-
4947
- .Table caption {
4948
- font-family: var(--sl-font-body-condense-font-family);
4949
- font-size: var(--sl-font-body-condense-font-size);
4950
- font-weight: var(--sl-font-body-condense-font-weight);
4951
- line-height: var(--sl-font-body-condense-line-height);
4952
- letter-spacing: var(--sl-font-body-condense-letter-spacing);
4953
- caption-side: bottom;
4954
- padding-block: var(--sl-space-2);
4955
- color: var(--sl-table-subtle-color);
4956
- text-align: start;
4957
- }
4958
-
4959
- /* Header: the tray band, a little taller than the rows */
4960
- .Table th {
4961
- font-family: var(--sl-font-subtitle-condense-font-family);
4962
- font-size: var(--sl-font-subtitle-condense-font-size);
4963
- font-weight: var(--sl-font-subtitle-condense-font-weight);
4964
- line-height: var(--sl-font-subtitle-condense-line-height);
4965
- letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
4966
- height: var(--sl-table-header-height);
4967
- padding-block: 0;
4968
- padding-inline: var(--sl-table-cell-padding-inline);
4969
- background: var(--sl-table-header-background);
4970
- color: var(--sl-table-header-color);
4971
- text-align: start;
4972
- vertical-align: middle;
4973
- border-bottom: var(--sl-stroke-default) solid var(--sl-table-border-color);
4974
- }
4975
-
4976
- /* A header that sorts: aria-sort on the th */
4977
- .Table th[aria-sort] {
4978
- cursor: pointer;
4979
- transition: background-color var(--sl-duration-fast) var(--sl-easing-default);
4980
- }
4981
-
4982
- .Table th[aria-sort]:hover {
4983
- background: var(--sl-table-header-background-hover);
4984
- }
4985
-
4986
- /* Body cells */
4987
- .Table td {
4988
- height: var(--sl-table-row-height);
4989
- padding-block: 0;
4990
- padding-inline: var(--sl-table-cell-padding-inline);
4991
- vertical-align: middle;
4992
- border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
4993
- }
4994
-
4995
- .Table tbody tr:last-child td,
4996
- .Table tbody:last-child tr:last-child td {
4997
- border-bottom: none;
4998
- }
4999
-
5000
- /* A row header (th in tbody) reads like a cell, in the header's weight */
5001
- .Table tbody th {
5002
- background: transparent;
5003
- border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
5004
- }
5005
-
5006
- /* Numbers and amounts: right-aligned so digits line up */
5007
- .Table [data-align='end'] {
5008
- text-align: end;
5009
- }
5010
-
5011
- .Table [data-align='center'] {
5012
- text-align: center;
5013
- }
5014
-
5015
- /* Secondary text in a cell */
5016
- .Table [data-subtle] {
5017
- color: var(--sl-table-subtle-color);
5018
- }
5019
-
5020
- /* Hover and selection: the same tints as list items */
5021
- @media (hover: hover) {
5022
- .Table tbody tr:hover > * {
5023
- background: var(--sl-table-row-hover);
5024
- color: var(--sl-item-color-hover);
5025
- }
5026
- }
5027
-
5028
- .Table tbody tr:is([aria-selected='true'], [data-selected]) > * {
5029
- background: var(--sl-table-row-selected);
5030
- color: var(--sl-item-color-selected);
5031
- }
5032
-
5033
- /* Footer: totals on the tray band */
5034
- .Table tfoot td {
5035
- font-family: var(--sl-font-subtitle-condense-font-family);
5036
- font-size: var(--sl-font-subtitle-condense-font-size);
5037
- font-weight: var(--sl-font-subtitle-condense-font-weight);
5038
- line-height: var(--sl-font-subtitle-condense-line-height);
5039
- letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
5040
- background: var(--sl-table-header-background);
5041
- border-top: var(--sl-stroke-default) solid var(--sl-table-border-color);
5042
- border-bottom: none;
5043
- }
5044
-
5045
- /* A header that stays put while the body scrolls (the table's wrapper scrolls) */
5046
- .Table[data-sticky-header] thead th {
5047
- position: sticky;
5048
- top: 0;
5049
- z-index: var(--sl-z-index-docked);
5050
- }
5051
-
5052
- /* Empty state: one cell spanning the columns */
5053
- .Table td[data-empty] {
5054
- height: auto;
5055
- padding-block: var(--sl-space-10);
5056
- color: var(--sl-text-tertiary);
5057
- text-align: center;
5058
- }
5059
-
5060
- .Table tbody tr:has(> td[data-empty]):hover > * {
5061
- background: transparent;
5062
- color: var(--sl-text-tertiary);
5063
- }
5064
-
5065
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
4920
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5066
4921
  /* Tabs - Mojave Theme
5067
4922
  *
5068
4923
  * No component tokens. The divider, the selected line and color, hover and the disabled
@@ -5198,7 +5053,7 @@ textarea.FieldControl {
5198
5053
  padding: var(--sl-space-6);
5199
5054
  }
5200
5055
 
5201
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
5056
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5202
5057
  /* Toast - Mojave Theme
5203
5058
  *
5204
5059
  * A toast is a notice (tokens/semantic/notice.json) on the popup surface. A toast whose type
@@ -5434,7 +5289,7 @@ textarea.FieldControl {
5434
5289
  flex-shrink: 0;
5435
5290
  }
5436
5291
 
5437
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
5292
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5438
5293
  /* Toggle - Mojave Theme
5439
5294
  * A toggle is a button that stays pressed: the same heights, padding, gap and
5440
5295
  * trigger text style as a button of the same size. Pressed, it takes its emphasis level's
@@ -5546,7 +5401,7 @@ textarea.FieldControl {
5546
5401
  height: var(--sl-icon-size-maximize);
5547
5402
  }
5548
5403
 
5549
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
5404
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5550
5405
  /* Toggle Group - Mojave Theme
5551
5406
  *
5552
5407
  * No component tokens. The strip is the bar concept (tokens/semantic/bar.json); the
@@ -5567,7 +5422,7 @@ textarea.FieldControl {
5567
5422
  border-radius: var(--sl-radius-item);
5568
5423
  }
5569
5424
 
5570
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
5425
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5571
5426
  /* Toolbar - Mojave Theme
5572
5427
  *
5573
5428
  * The strip is the bar concept (tokens/semantic/bar.json). Buttons, toggles, selects
@@ -5629,7 +5484,7 @@ textarea.FieldControl {
5629
5484
  max-width: var(--sl-toolbar-input-max-width);
5630
5485
  }
5631
5486
 
5632
- /* @scattered-light/loomiere-base-ui 0.6.0 · styles for @base-ui/react 1.9.0 */
5487
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5633
5488
  /* Tooltip - Mojave Theme
5634
5489
  *
5635
5490
  * The inverse surface (surface.inverse, text.on-inverse-surface) with condense text, so a tooltip
@@ -5688,3 +5543,2228 @@ textarea.FieldControl {
5688
5543
  transform: none;
5689
5544
  }
5690
5545
  }
5546
+
5547
+ /* Custom components: not Base UI parts. Built from existing concepts and tokens. */
5548
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5549
+ /* Badge
5550
+ *
5551
+ * A status or count label. Not a Base UI part, and not interactive: no hover or focus.
5552
+ * Colors are the emphasis levels (--sl-e-bg, --sl-e-fg, --sl-e-border), so data-emphasis,
5553
+ * data-status and data-color all recolor it. The default level is subtle, from
5554
+ * DEFAULT_LEVELS. The shape is radius.pill. Sizes are badge.* (tokens/component/badge.json).
5555
+ *
5556
+ * Text is the trigger style of the same tier (trigger-minimize, trigger-condense,
5557
+ * trigger-base): medium weight, and those three tiers already exist. subtitle is bold,
5558
+ * which would shout, and label only exists at base. Icons use icon-size of that same
5559
+ * tier (a badge icon is a mark beside the label, not a control that fills the line the
5560
+ * way a Button icon does).
5561
+ *
5562
+ * Min width equals the height on every badge, so a single digit is a circle and a
5563
+ * wider label is unchanged. Padding stays, so "12" does not touch the pill edges.
5564
+ */
5565
+
5566
+ .Badge {
5567
+ font-family: var(--sl-font-trigger-condense-font-family);
5568
+ font-size: var(--sl-font-trigger-condense-font-size);
5569
+ font-weight: var(--sl-font-trigger-condense-font-weight);
5570
+ line-height: var(--sl-font-trigger-condense-line-height);
5571
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
5572
+ display: inline-flex;
5573
+ align-items: center;
5574
+ justify-content: center;
5575
+ gap: var(--sl-badge-gap-condense);
5576
+ height: var(--sl-badge-height-condense);
5577
+ min-width: var(--sl-badge-height-condense);
5578
+ padding-inline: var(--sl-badge-padding-inline-condense);
5579
+ border: var(--sl-stroke-default) solid var(--sl-e-border);
5580
+ border-radius: var(--sl-radius-pill);
5581
+ background: var(--sl-e-bg);
5582
+ color: var(--sl-e-fg);
5583
+ white-space: nowrap;
5584
+ }
5585
+
5586
+ .Badge[data-size='minimize'] {
5587
+ font-family: var(--sl-font-trigger-minimize-font-family);
5588
+ font-size: var(--sl-font-trigger-minimize-font-size);
5589
+ font-weight: var(--sl-font-trigger-minimize-font-weight);
5590
+ line-height: var(--sl-font-trigger-minimize-line-height);
5591
+ letter-spacing: var(--sl-font-trigger-minimize-letter-spacing);
5592
+ gap: var(--sl-badge-gap-minimize);
5593
+ height: var(--sl-badge-height-minimize);
5594
+ min-width: var(--sl-badge-height-minimize);
5595
+ padding-inline: var(--sl-badge-padding-inline-minimize);
5596
+ }
5597
+
5598
+ .Badge[data-size='base'] {
5599
+ font-family: var(--sl-font-trigger-base-font-family);
5600
+ font-size: var(--sl-font-trigger-base-font-size);
5601
+ font-weight: var(--sl-font-trigger-base-font-weight);
5602
+ line-height: var(--sl-font-trigger-base-line-height);
5603
+ letter-spacing: var(--sl-font-trigger-base-letter-spacing);
5604
+ gap: var(--sl-badge-gap-base);
5605
+ height: var(--sl-badge-height-base);
5606
+ min-width: var(--sl-badge-height-base);
5607
+ padding-inline: var(--sl-badge-padding-inline-base);
5608
+ }
5609
+
5610
+ .Badge svg,
5611
+ .Badge .material-symbols-outlined {
5612
+ width: var(--sl-icon-size-condense);
5613
+ height: var(--sl-icon-size-condense);
5614
+ font-size: var(--sl-icon-size-condense);
5615
+ line-height: 1;
5616
+ flex-shrink: 0;
5617
+ }
5618
+
5619
+ .Badge[data-size='minimize'] svg,
5620
+ .Badge[data-size='minimize'] .material-symbols-outlined {
5621
+ width: var(--sl-icon-size-minimize);
5622
+ height: var(--sl-icon-size-minimize);
5623
+ font-size: var(--sl-icon-size-minimize);
5624
+ }
5625
+
5626
+ .Badge[data-size='base'] svg,
5627
+ .Badge[data-size='base'] .material-symbols-outlined {
5628
+ width: var(--sl-icon-size-base);
5629
+ height: var(--sl-icon-size-base);
5630
+ font-size: var(--sl-icon-size-base);
5631
+ }
5632
+
5633
+ /* A status dot, in the label color. */
5634
+ .Badge[data-dot]::before {
5635
+ content: '';
5636
+ width: var(--sl-badge-dot-condense);
5637
+ height: var(--sl-badge-dot-condense);
5638
+ border-radius: var(--sl-radius-pill);
5639
+ background: currentColor;
5640
+ flex-shrink: 0;
5641
+ }
5642
+
5643
+ .Badge[data-size='minimize'][data-dot]::before {
5644
+ width: var(--sl-badge-dot-minimize);
5645
+ height: var(--sl-badge-dot-minimize);
5646
+ }
5647
+
5648
+ .Badge[data-size='base'][data-dot]::before {
5649
+ width: var(--sl-badge-dot-base);
5650
+ height: var(--sl-badge-dot-base);
5651
+ }
5652
+
5653
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
5654
+ /*
5655
+ * DatePicker: a field that opens a calendar for one date or a period.
5656
+ * Not a Base UI part. The popup is Popover on a wide viewport and Drawer
5657
+ * below the md breakpoint. Calendar is the grid on its own; DatePresets is
5658
+ * the quick-selection list. Both are usable without the field.
5659
+ *
5660
+ * Concepts: calendar (day cell, range band, today ring), item (preset rows),
5661
+ * field (the trigger), emphasis bold (the selected day, via the default
5662
+ * emphasis level, so it follows data-color).
5663
+ *
5664
+ * Text styles, one whole style each: day numbers are trigger-condense and
5665
+ * selected days are selected-condense, weekday initials are eyebrow-minimize,
5666
+ * the month title is subtitle-base, a preset label is trigger-condense with
5667
+ * its hint in body-minimize, and the footer summary is body-condense.
5668
+ * The trigger text is text-body-base, the same style as Input.
5669
+ *
5670
+ * How many months are on screen is measured on the panel (40rem two months,
5671
+ * 32rem one, and one month in a drawer or for a coarse pointer under 48rem).
5672
+ * Those lengths are layout, not tokens. CSS only switches the preset row and
5673
+ * the sticky footer, from data-layout and data-compact.
5674
+ *
5675
+ * Keyboard (WAI-ARIA APG date picker dialog): Left/Right one day (they swap
5676
+ * in RTL), Up/Down one week, Home/End the week, PageUp/PageDown one month,
5677
+ * Shift+PageUp/PageDown one year, Enter/Space pick. With two months showing,
5678
+ * paging forward lands the focused day in the last column, so the view shifts
5679
+ * by one month. Delete or Backspace clears the draft. Escape drops a
5680
+ * half-picked range first, then closes. Escape in the month or year chooser
5681
+ * returns to the days. A range is a start click, then an end click; an end
5682
+ * before the start swaps. Hover or focus previews the band until the end is
5683
+ * chosen. Direction is read when the picker opens; a dir change while it is
5684
+ * open is not picked up.
5685
+ *
5686
+ * Day state: data-selected, data-range-start, data-range-end, data-in-range,
5687
+ * data-preview, data-today, data-outside-month, data-disabled, data-focused.
5688
+ * aria-selected is only the real value (the day, or the start and end).
5689
+ */
5690
+
5691
+ /* CALENDAR */
5692
+
5693
+ .Calendar {
5694
+ display: flex;
5695
+ flex-direction: column;
5696
+ gap: var(--sl-calendar-month-gap);
5697
+ min-width: 0;
5698
+ }
5699
+
5700
+ .DatePickerMonths {
5701
+ display: flex;
5702
+ flex-wrap: wrap;
5703
+ gap: var(--sl-calendar-month-gap);
5704
+ min-width: 0;
5705
+ }
5706
+
5707
+ .DatePickerNav {
5708
+ display: flex;
5709
+ align-items: center;
5710
+ gap: var(--sl-calendar-header-gap);
5711
+ flex: 1 0 100%;
5712
+ }
5713
+
5714
+ .DatePickerNav .DatePickerMonthTitle {
5715
+ flex: 1 1 auto;
5716
+ }
5717
+
5718
+ .DatePickerMonth {
5719
+ display: flex;
5720
+ flex-direction: column;
5721
+ gap: var(--sl-calendar-header-gap);
5722
+ min-width: 0;
5723
+ flex: 1 1 auto;
5724
+ }
5725
+
5726
+ .DatePickerMonthBar {
5727
+ display: flex;
5728
+ align-items: center;
5729
+ justify-content: space-between;
5730
+ gap: var(--sl-calendar-header-gap);
5731
+ min-height: var(--sl-control-height-sm);
5732
+ }
5733
+
5734
+ .DatePickerMonthSpacer {
5735
+ inline-size: var(--sl-control-height-sm);
5736
+ flex: 0 0 auto;
5737
+ }
5738
+
5739
+ .DatePickerMonthTitle {
5740
+ font-family: var(--sl-font-subtitle-base-font-family);
5741
+ font-size: var(--sl-font-subtitle-base-font-size);
5742
+ font-weight: var(--sl-font-subtitle-base-font-weight);
5743
+ line-height: var(--sl-font-subtitle-base-line-height);
5744
+ letter-spacing: var(--sl-font-subtitle-base-letter-spacing);
5745
+ outline: none;
5746
+ margin: 0;
5747
+ padding: var(--sl-space-1) var(--sl-space-2);
5748
+ border: 0;
5749
+ border-radius: var(--sl-radius-control);
5750
+ background: transparent;
5751
+ color: var(--sl-text-primary);
5752
+ cursor: pointer;
5753
+ }
5754
+
5755
+ .DatePickerMonthTitle:hover {
5756
+ background: var(--sl-item-background-hover);
5757
+ }
5758
+
5759
+ .DatePickerMonthTitle:focus-visible {
5760
+ outline: var(--sl-focus-outline);
5761
+ outline-offset: var(--sl-focus-outline-offset);
5762
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
5763
+ }
5764
+
5765
+ .CalendarGrid {
5766
+ display: flex;
5767
+ flex-direction: column;
5768
+ gap: var(--sl-calendar-grid-gap);
5769
+ }
5770
+
5771
+ .Calendar,
5772
+ .DatePickerPanel {
5773
+ --sl-calendar-cell: var(--sl-calendar-day-size);
5774
+ }
5775
+
5776
+ .DatePickerPanel[data-touch] {
5777
+ --sl-calendar-cell: max(var(--sl-calendar-day-size), var(--sl-a11y-min-touch-target));
5778
+ }
5779
+
5780
+ @media (pointer: coarse) {
5781
+ .Calendar {
5782
+ --sl-calendar-cell: max(var(--sl-calendar-day-size), var(--sl-a11y-min-touch-target));
5783
+ }
5784
+ }
5785
+
5786
+ .CalendarWeek {
5787
+ display: grid;
5788
+ grid-template-columns: repeat(7, var(--sl-calendar-cell));
5789
+ column-gap: 0;
5790
+ row-gap: var(--sl-calendar-grid-gap);
5791
+ }
5792
+
5793
+ .CalendarGrid:has(.CalendarWeekNumber) .CalendarWeek {
5794
+ grid-template-columns: auto repeat(7, var(--sl-calendar-cell));
5795
+ }
5796
+
5797
+ .CalendarWeekday,
5798
+ .CalendarWeekNumber {
5799
+ font-family: var(--sl-font-eyebrow-minimize-font-family);
5800
+ font-size: var(--sl-font-eyebrow-minimize-font-size);
5801
+ font-weight: var(--sl-font-eyebrow-minimize-font-weight);
5802
+ line-height: var(--sl-font-eyebrow-minimize-line-height);
5803
+ letter-spacing: var(--sl-font-eyebrow-minimize-letter-spacing);
5804
+ text-transform: var(--sl-font-eyebrow-minimize-text-transform);
5805
+ display: grid;
5806
+ place-items: center;
5807
+ min-block-size: var(--sl-space-6);
5808
+ color: var(--sl-calendar-weekday-color);
5809
+ text-decoration: none;
5810
+ }
5811
+
5812
+ .CalendarWeekNumber {
5813
+ padding-inline: var(--sl-space-1);
5814
+ }
5815
+
5816
+ .CalendarDay {
5817
+ font-family: var(--sl-font-trigger-condense-font-family);
5818
+ font-size: var(--sl-font-trigger-condense-font-size);
5819
+ font-weight: var(--sl-font-trigger-condense-font-weight);
5820
+ line-height: var(--sl-font-trigger-condense-line-height);
5821
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
5822
+ position: relative;
5823
+ display: grid;
5824
+ place-items: center;
5825
+ box-sizing: border-box;
5826
+ inline-size: 100%;
5827
+ aspect-ratio: 1;
5828
+ min-inline-size: 0;
5829
+ min-block-size: 0;
5830
+ padding: 0;
5831
+ border: 0;
5832
+ border-radius: var(--sl-calendar-day-radius);
5833
+ outline: none;
5834
+ background: transparent;
5835
+ color: var(--sl-calendar-day-color);
5836
+ cursor: pointer;
5837
+ }
5838
+
5839
+ .CalendarDay:focus-visible {
5840
+ outline: var(--sl-focus-outline);
5841
+ outline-offset: var(--sl-focus-outline-offset);
5842
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
5843
+ }
5844
+
5845
+ .CalendarDay--empty {
5846
+ cursor: default;
5847
+ pointer-events: none;
5848
+ }
5849
+
5850
+ .CalendarDayNumber {
5851
+ position: relative;
5852
+ z-index: 1;
5853
+ }
5854
+
5855
+ .CalendarDay:hover:not([data-disabled]):not([data-selected]) {
5856
+ background: var(--sl-calendar-day-background-hover);
5857
+ }
5858
+
5859
+ .CalendarDay[data-outside-month] {
5860
+ color: var(--sl-calendar-day-color-outside);
5861
+ }
5862
+
5863
+ .CalendarDay[data-disabled] {
5864
+ color: var(--sl-calendar-day-color-disabled);
5865
+ cursor: default;
5866
+ }
5867
+
5868
+ .CalendarDay[data-selected] {
5869
+ font-family: var(--sl-font-selected-condense-font-family);
5870
+ font-size: var(--sl-font-selected-condense-font-size);
5871
+ font-weight: var(--sl-font-selected-condense-font-weight);
5872
+ line-height: var(--sl-font-selected-condense-line-height);
5873
+ letter-spacing: var(--sl-font-selected-condense-letter-spacing);
5874
+ }
5875
+
5876
+ .CalendarDay[data-selected]:not([data-range-start]):not([data-range-end]) {
5877
+ background: var(--sl-e-bg);
5878
+ color: var(--sl-e-fg);
5879
+ }
5880
+
5881
+ .CalendarDay[data-range-start],
5882
+ .CalendarDay[data-range-end] {
5883
+ overflow: hidden;
5884
+ background: transparent;
5885
+ }
5886
+
5887
+ .CalendarDay[data-range-start] .CalendarDayNumber,
5888
+ .CalendarDay[data-range-end] .CalendarDayNumber {
5889
+ display: grid;
5890
+ place-items: center;
5891
+ inline-size: 100%;
5892
+ block-size: 100%;
5893
+ border-radius: var(--sl-calendar-day-radius);
5894
+ background: var(--sl-e-bg);
5895
+ color: var(--sl-e-fg);
5896
+ }
5897
+
5898
+ .CalendarDay[data-in-range],
5899
+ .CalendarDay[data-preview]:not([data-selected]) {
5900
+ border-radius: 0;
5901
+ background: var(--sl-calendar-range-background);
5902
+ color: var(--sl-calendar-range-color);
5903
+ }
5904
+
5905
+ .CalendarDay[data-range-start]::before,
5906
+ .CalendarDay[data-range-end]::before {
5907
+ content: '';
5908
+ position: absolute;
5909
+ inset: 0;
5910
+ z-index: 0;
5911
+ background: linear-gradient(to right, transparent 50%, var(--sl-calendar-range-background) 50%);
5912
+ }
5913
+
5914
+ .CalendarDay[data-range-end]::before {
5915
+ background: linear-gradient(to left, transparent 50%, var(--sl-calendar-range-background) 50%);
5916
+ }
5917
+
5918
+ [dir='rtl'] .CalendarDay[data-range-start]::before {
5919
+ background: linear-gradient(to left, transparent 50%, var(--sl-calendar-range-background) 50%);
5920
+ }
5921
+
5922
+ [dir='rtl'] .CalendarDay[data-range-end]::before {
5923
+ background: linear-gradient(to right, transparent 50%, var(--sl-calendar-range-background) 50%);
5924
+ }
5925
+
5926
+ .CalendarDay[data-range-start][data-range-end]::before {
5927
+ content: none;
5928
+ }
5929
+
5930
+ .CalendarDay[data-focused] {
5931
+ z-index: 1;
5932
+ }
5933
+
5934
+ .CalendarDay[data-today] .CalendarDayNumber {
5935
+ box-shadow: inset 0 0 0 var(--sl-stroke-default) var(--sl-calendar-today-ring);
5936
+ border-radius: var(--sl-calendar-day-radius);
5937
+ padding-inline: var(--sl-space-1);
5938
+ }
5939
+
5940
+ /* The selected fill is the bold accent, the same hue as the today ring, so the ring switches to the text color. */
5941
+ .CalendarDay[data-today][data-selected] .CalendarDayNumber {
5942
+ box-shadow: inset 0 0 0 var(--sl-stroke-default) var(--sl-e-fg);
5943
+ }
5944
+
5945
+ [data-theme$='high-contrast'] .CalendarDay[data-in-range],
5946
+ [data-theme$='high-contrast'] .CalendarDay[data-preview]:not([data-selected]) {
5947
+ box-shadow: inset 0 calc(var(--sl-stroke-default) * -1) 0 var(--sl-border-accent);
5948
+ }
5949
+
5950
+ .CalendarChooser {
5951
+ display: flex;
5952
+ flex-direction: column;
5953
+ gap: var(--sl-calendar-header-gap);
5954
+ }
5955
+
5956
+ .CalendarChooserGrid {
5957
+ display: grid;
5958
+ grid-template-columns: repeat(3, minmax(0, 1fr));
5959
+ gap: var(--sl-calendar-grid-gap);
5960
+ }
5961
+
5962
+ .CalendarChoice {
5963
+ font-family: var(--sl-font-trigger-condense-font-family);
5964
+ font-size: var(--sl-font-trigger-condense-font-size);
5965
+ font-weight: var(--sl-font-trigger-condense-font-weight);
5966
+ line-height: var(--sl-font-trigger-condense-line-height);
5967
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
5968
+ outline: none;
5969
+ min-block-size: var(--sl-control-height-sm);
5970
+ padding: var(--sl-space-1) var(--sl-space-2);
5971
+ border: 0;
5972
+ border-radius: var(--sl-radius-control);
5973
+ background: transparent;
5974
+ color: var(--sl-text-primary);
5975
+ cursor: pointer;
5976
+ }
5977
+
5978
+ .CalendarChoice:hover:not([aria-disabled='true']) {
5979
+ background: var(--sl-item-background-hover);
5980
+ }
5981
+
5982
+ .CalendarChoice:focus-visible {
5983
+ outline: var(--sl-focus-outline);
5984
+ outline-offset: var(--sl-focus-outline-offset);
5985
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
5986
+ }
5987
+
5988
+ .CalendarChoice[aria-disabled='true'] {
5989
+ color: var(--sl-calendar-day-color-disabled);
5990
+ cursor: default;
5991
+ }
5992
+
5993
+ /* PRESETS */
5994
+
5995
+ .DatePickerPresets {
5996
+ display: flex;
5997
+ flex-direction: column;
5998
+ gap: var(--sl-space-1);
5999
+ min-width: 0;
6000
+ }
6001
+
6002
+ .DatePickerPresets[data-layout='row'] {
6003
+ flex-direction: row;
6004
+ overflow-x: auto;
6005
+ }
6006
+
6007
+ .DatePickerPreset {
6008
+ font-family: var(--sl-font-trigger-condense-font-family);
6009
+ font-size: var(--sl-font-trigger-condense-font-size);
6010
+ font-weight: var(--sl-font-trigger-condense-font-weight);
6011
+ line-height: var(--sl-font-trigger-condense-line-height);
6012
+ letter-spacing: var(--sl-font-trigger-condense-letter-spacing);
6013
+ outline: none;
6014
+ display: flex;
6015
+ flex-direction: column;
6016
+ align-items: flex-start;
6017
+ gap: var(--sl-space-0-5);
6018
+ inline-size: 100%;
6019
+ padding: var(--sl-item-padding-block) var(--sl-item-padding-inline);
6020
+ border: 0;
6021
+ border-radius: var(--sl-item-radius);
6022
+ background: transparent;
6023
+ color: var(--sl-item-color);
6024
+ text-align: start;
6025
+ cursor: pointer;
6026
+ }
6027
+
6028
+ .DatePickerPresets[data-layout='row'] .DatePickerPreset {
6029
+ flex-direction: row;
6030
+ align-items: baseline;
6031
+ inline-size: auto;
6032
+ white-space: nowrap;
6033
+ }
6034
+
6035
+ .DatePickerPreset:hover:not([data-disabled]) {
6036
+ background: var(--sl-item-background-hover);
6037
+ }
6038
+
6039
+ .DatePickerPreset:focus-visible {
6040
+ outline: var(--sl-focus-outline);
6041
+ outline-offset: var(--sl-focus-outline-offset);
6042
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
6043
+ }
6044
+
6045
+ .DatePickerPreset[data-checked] {
6046
+ background: var(--sl-item-background-selected);
6047
+ color: var(--sl-item-color-selected);
6048
+ }
6049
+
6050
+ .DatePickerPreset[data-disabled] {
6051
+ color: var(--sl-text-disabled);
6052
+ cursor: default;
6053
+ }
6054
+
6055
+ .DatePickerPresetHint {
6056
+ font-family: var(--sl-font-body-minimize-font-family);
6057
+ font-size: var(--sl-font-body-minimize-font-size);
6058
+ font-weight: var(--sl-font-body-minimize-font-weight);
6059
+ line-height: var(--sl-font-body-minimize-line-height);
6060
+ letter-spacing: var(--sl-font-body-minimize-letter-spacing);
6061
+ color: var(--sl-text-tertiary);
6062
+ }
6063
+
6064
+ .DatePickerPreset[data-checked] .DatePickerPresetHint {
6065
+ color: var(--sl-item-color-selected);
6066
+ }
6067
+
6068
+ /* PICKER */
6069
+
6070
+ .DatePickerField {
6071
+ position: relative;
6072
+ display: flex;
6073
+ align-items: center;
6074
+ min-width: 0;
6075
+ }
6076
+
6077
+ .DatePickerField .DatePickerTrigger {
6078
+ box-sizing: border-box;
6079
+ color: var(--sl-field-color);
6080
+ background: var(--sl-field-background);
6081
+ border: var(--sl-field-border-width) solid var(--sl-field-border-color);
6082
+ border-radius: var(--sl-field-radius);
6083
+ transition: var(--sl-field-transition);
6084
+ outline: none;
6085
+ font-family: var(--sl-font-body-base-font-family);
6086
+ font-size: var(--sl-font-body-base-font-size);
6087
+ font-weight: var(--sl-font-body-base-font-weight);
6088
+ line-height: var(--sl-font-body-base-line-height);
6089
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
6090
+ outline: none;
6091
+ display: inline-flex;
6092
+ align-items: center;
6093
+ gap: var(--sl-gap-control);
6094
+ inline-size: 100%;
6095
+ block-size: var(--sl-control-height-md);
6096
+ padding-inline: var(--sl-control-padding-inline);
6097
+ text-align: start;
6098
+ cursor: pointer;
6099
+ }
6100
+
6101
+ .DatePickerTrigger:disabled {
6102
+ color: var(--sl-text-disabled);
6103
+ cursor: default;
6104
+ }
6105
+
6106
+ .DatePickerField .DatePickerTrigger:focus-visible {
6107
+ outline: var(--sl-focus-outline);
6108
+ outline-offset: var(--sl-focus-outline-offset);
6109
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
6110
+ }
6111
+
6112
+ .DatePickerValue[data-placeholder] {
6113
+ color: var(--sl-text-tertiary);
6114
+ }
6115
+
6116
+ .DatePickerClear {
6117
+ position: absolute;
6118
+ inset-inline-end: var(--sl-space-1);
6119
+ z-index: 1;
6120
+ }
6121
+
6122
+ .DatePickerTrigger:has(~ .DatePickerClear) {
6123
+ padding-inline-end: var(--sl-control-height-sm);
6124
+ }
6125
+
6126
+ .DatePickerPopup {
6127
+ /* 52rem fits two months and the preset column; three months ask for 64rem. Layout, not a brand size. */
6128
+ inline-size: min(var(--available-width, 100vw), 52rem);
6129
+ max-inline-size: var(--available-width, 100vw);
6130
+ padding: 0;
6131
+ }
6132
+
6133
+ .DatePickerPopup[data-months='3'] {
6134
+ inline-size: min(var(--available-width, 100vw), 64rem);
6135
+ }
6136
+
6137
+ .DatePickerPanel {
6138
+ display: grid;
6139
+ /* 11rem is the preset column. Layout, not a brand size: wide enough for "Year to date" and a hint. */
6140
+ grid-template-columns: 11rem minmax(0, 1fr);
6141
+ align-items: start;
6142
+ gap: var(--sl-calendar-month-gap);
6143
+ padding: var(--sl-calendar-panel-padding);
6144
+ min-width: 0;
6145
+ }
6146
+
6147
+ .DatePickerPanel .DatePickerPresets {
6148
+ grid-column: 1;
6149
+ grid-row: 1 / span 2;
6150
+ inline-size: auto;
6151
+ }
6152
+
6153
+ .DatePickerPanel .Calendar {
6154
+ grid-column: 2;
6155
+ grid-row: 1;
6156
+ min-width: 0;
6157
+ }
6158
+
6159
+ .DatePickerPanel:not(:has(.DatePickerPresets)) {
6160
+ grid-template-columns: minmax(0, 1fr);
6161
+ }
6162
+
6163
+ .DatePickerPanel:not(:has(.DatePickerPresets)) .Calendar,
6164
+ .DatePickerPanel:not(:has(.DatePickerPresets)) .DatePickerFooter {
6165
+ grid-column: 1;
6166
+ }
6167
+
6168
+ .DatePickerFooter {
6169
+ display: flex;
6170
+ align-items: center;
6171
+ justify-content: space-between;
6172
+ gap: var(--sl-space-3);
6173
+ grid-column: 2;
6174
+ grid-row: 2;
6175
+ }
6176
+
6177
+ .DatePickerSummary {
6178
+ font-family: var(--sl-font-body-condense-font-family);
6179
+ font-size: var(--sl-font-body-condense-font-size);
6180
+ font-weight: var(--sl-font-body-condense-font-weight);
6181
+ line-height: var(--sl-font-body-condense-line-height);
6182
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
6183
+ margin: 0;
6184
+ color: var(--sl-text-secondary);
6185
+ }
6186
+
6187
+ .DatePickerActions {
6188
+ display: flex;
6189
+ gap: var(--sl-space-2);
6190
+ margin-inline-start: auto;
6191
+ }
6192
+
6193
+ /* Presets become a row once the measured panel is under 40rem, or the popup is a drawer. */
6194
+ .DatePickerPanel[data-layout='row'],
6195
+ .DatePickerPanel[data-layout='row']:not(:has(.DatePickerPresets)) {
6196
+ grid-template-columns: minmax(0, 1fr);
6197
+ }
6198
+
6199
+ .DatePickerPanel[data-layout='row'] .DatePickerPresets,
6200
+ .DatePickerPanel[data-layout='row'] .Calendar,
6201
+ .DatePickerPanel[data-layout='row'] .DatePickerFooter {
6202
+ grid-column: 1;
6203
+ grid-row: auto;
6204
+ }
6205
+
6206
+ .DatePickerPanel[data-compact] .DatePickerFooter {
6207
+ position: sticky;
6208
+ inset-block-end: 0;
6209
+ flex-wrap: wrap;
6210
+ background: var(--sl-popup-background);
6211
+ }
6212
+
6213
+ /* The action row shrinks to its buttons, so a percentage width on Apply never
6214
+ resolves. A 100% basis wraps Apply onto its own row of the footer. */
6215
+ .DatePickerPanel[data-compact] .DatePickerActions {
6216
+ flex-basis: 100%;
6217
+ flex-wrap: wrap;
6218
+ justify-content: flex-end;
6219
+ margin-inline-start: 0;
6220
+ }
6221
+
6222
+ .DatePickerPanel[data-compact] .DatePickerApply {
6223
+ flex-basis: 100%;
6224
+ }
6225
+
6226
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6227
+ /* Money field
6228
+ *
6229
+ * An amount of money, built on Number field. The value is an integer in minor units
6230
+ * (cents, yen, fils) so 0.1 + 0.2 and 1.005 * 100 cannot drift, and so the number matches
6231
+ * what a payment API sends. Number field counts in major units; Money field converts at
6232
+ * the edge and rounds half away from zero. The default maximum is 10^15 - 1 minor
6233
+ * units, so the major amount stays inside 15 significant digits. Changing currency
6234
+ * keeps the number the person typed and re-rounds it to the new currency's digits
6235
+ * (12.50 USD becomes 13 JPY). There is no exchange rate. When the app
6236
+ * controls both the value and the currency, it decides whether to apply that rounding:
6237
+ * onValueChange still reports the re-rounded minor units.
6238
+ *
6239
+ * Keyboard is Number field's: ArrowUp and ArrowDown step one major unit, Shift steps 100
6240
+ * major units, Alt steps one minor unit, Home and End jump to the minimum and maximum.
6241
+ * The currency symbol is not in the text, so the caret does not fight it. A fixed symbol
6242
+ * is aria-hidden; the currency name is in the input's accessible description. A picker
6243
+ * is its own tab stop, before the input when the locale puts the symbol first and after
6244
+ * it when the locale puts the symbol last.
6245
+ *
6246
+ * State on the root: data-currency (USD), data-affix (start or end), data-affix-kind
6247
+ * (symbol or picker), data-negative (below zero; set data-color on the field to color
6248
+ * it, never on by default), data-align (start or end),
6249
+ * data-size (xs, sm, md, lg), data-readonly, plus data-invalid, data-disabled,
6250
+ * data-focused and data-scrubbing.
6251
+ *
6252
+ * The affix (symbol or picker) is drawn inside the field so it can later be lifted into
6253
+ * a general Input affix for units, https://, or @. Position comes from the locale, with
6254
+ * logical properties so RTL mirrors it. The group, not the input, carries the field
6255
+ * border, hover, focus halo, invalid edge and disabled fill, so the affix reads as part
6256
+ * of the field.
6257
+ */
6258
+
6259
+ /* ============================================
6260
+ FIELD
6261
+ ============================================ */
6262
+
6263
+ .MoneyField {
6264
+ display: inline-flex;
6265
+ flex-direction: column;
6266
+ gap: var(--sl-field-gap);
6267
+ width: 100%;
6268
+ }
6269
+
6270
+ .MoneyFieldGroup {
6271
+ box-sizing: border-box;
6272
+ color: var(--sl-field-color);
6273
+ background: var(--sl-field-background);
6274
+ border: var(--sl-field-border-width) solid var(--sl-field-border-color);
6275
+ border-radius: var(--sl-field-radius);
6276
+ transition: var(--sl-field-transition);
6277
+ outline: none;
6278
+ font-family: var(--sl-font-body-base-font-family);
6279
+ font-size: var(--sl-font-body-base-font-size);
6280
+ font-weight: var(--sl-font-body-base-font-weight);
6281
+ line-height: var(--sl-font-body-base-line-height);
6282
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
6283
+ display: flex;
6284
+ align-items: stretch;
6285
+ width: 100%;
6286
+ height: var(--sl-control-height-md);
6287
+ padding: 0;
6288
+ }
6289
+
6290
+ .MoneyField[data-size='xs'] .MoneyFieldGroup {
6291
+ font-family: var(--sl-font-body-minimize-font-family);
6292
+ font-size: var(--sl-font-body-minimize-font-size);
6293
+ font-weight: var(--sl-font-body-minimize-font-weight);
6294
+ line-height: var(--sl-font-body-minimize-line-height);
6295
+ letter-spacing: var(--sl-font-body-minimize-letter-spacing);
6296
+ height: var(--sl-control-height-xs);
6297
+ }
6298
+
6299
+ .MoneyField[data-size='sm'] .MoneyFieldGroup {
6300
+ font-family: var(--sl-font-body-condense-font-family);
6301
+ font-size: var(--sl-font-body-condense-font-size);
6302
+ font-weight: var(--sl-font-body-condense-font-weight);
6303
+ line-height: var(--sl-font-body-condense-line-height);
6304
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
6305
+ height: var(--sl-control-height-sm);
6306
+ }
6307
+
6308
+ .MoneyField[data-size='lg'] .MoneyFieldGroup {
6309
+ font-family: var(--sl-font-body-magnify-font-family);
6310
+ font-size: var(--sl-font-body-magnify-font-size);
6311
+ font-weight: var(--sl-font-body-magnify-font-weight);
6312
+ line-height: var(--sl-font-body-magnify-line-height);
6313
+ letter-spacing: var(--sl-font-body-magnify-letter-spacing);
6314
+ height: var(--sl-control-height-lg);
6315
+ }
6316
+
6317
+ .MoneyFieldGroup .MoneyFieldInput,
6318
+ .MoneyFieldAffix,
6319
+ .MoneyFieldGroup .MoneyFieldCurrencyTrigger {
6320
+ font: inherit;
6321
+ }
6322
+
6323
+ .MoneyFieldGroup .MoneyFieldInput {
6324
+ flex: 1;
6325
+ min-inline-size: 0;
6326
+ height: auto;
6327
+ border: 0;
6328
+ border-radius: 0;
6329
+ background: transparent;
6330
+ box-shadow: none;
6331
+ outline: none;
6332
+ font-variant-numeric: tabular-nums;
6333
+ }
6334
+
6335
+ .MoneyFieldGroup .MoneyFieldInput:hover,
6336
+ .MoneyFieldGroup .MoneyFieldInput:focus,
6337
+ .MoneyField[data-invalid] .MoneyFieldInput,
6338
+ .MoneyField[data-invalid] .MoneyFieldInput:focus,
6339
+ .MoneyField[data-disabled] .MoneyFieldInput {
6340
+ border-color: transparent;
6341
+ background: transparent;
6342
+ box-shadow: none;
6343
+ }
6344
+
6345
+ /* A symbol brings its own padding. A picker has a divider, so the amount keeps its inset. */
6346
+ .MoneyField[data-affix-kind='symbol'][data-affix='start'] .MoneyFieldInput {
6347
+ padding-inline-start: 0;
6348
+ }
6349
+
6350
+ .MoneyField[data-affix-kind='symbol'][data-affix='end']:not([data-steppers]) .MoneyFieldInput {
6351
+ padding-inline-end: 0;
6352
+ }
6353
+
6354
+ /* Number field always pads for its steppers. Those buttons are absent unless asked for. */
6355
+ .MoneyField:not([data-steppers]) .MoneyFieldInput {
6356
+ padding-inline-end: var(--sl-control-padding-inline);
6357
+ }
6358
+
6359
+ .MoneyField[data-size='xs']:not([data-steppers]) .MoneyFieldInput {
6360
+ padding-inline-end: var(--sl-control-padding-inline-xs);
6361
+ }
6362
+
6363
+ .MoneyField[data-size='sm']:not([data-steppers]) .MoneyFieldInput {
6364
+ padding-inline-end: var(--sl-control-padding-inline-sm);
6365
+ }
6366
+
6367
+ .MoneyField[data-size='lg']:not([data-steppers]) .MoneyFieldInput {
6368
+ padding-inline-end: var(--sl-control-padding-inline-lg);
6369
+ }
6370
+
6371
+ .MoneyField[data-align='end'] .MoneyFieldInput {
6372
+ text-align: end;
6373
+ }
6374
+
6375
+ .MoneyField[data-align='start'] .MoneyFieldInput {
6376
+ text-align: start;
6377
+ }
6378
+
6379
+ .MoneyFieldGroup:hover:not(:focus-within) {
6380
+ border-color: var(--sl-field-border-color-hover);
6381
+ }
6382
+
6383
+ .MoneyFieldGroup:focus-within,
6384
+ .MoneyField[data-focused] .MoneyFieldGroup {
6385
+ border-color: var(--sl-field-border-color-focus);
6386
+ box-shadow: var(--sl-field-shadow-focus);
6387
+ }
6388
+
6389
+ .MoneyField[data-invalid] .MoneyFieldGroup {
6390
+ border-color: var(--sl-field-border-color-error);
6391
+ }
6392
+
6393
+ .MoneyField[data-invalid] .MoneyFieldGroup:focus-within,
6394
+ .MoneyField[data-invalid][data-focused] .MoneyFieldGroup {
6395
+ border-color: var(--sl-field-border-color-error);
6396
+ box-shadow: var(--sl-field-shadow-focus-error);
6397
+ }
6398
+
6399
+ .MoneyField[data-disabled] .MoneyFieldGroup {
6400
+ background: var(--sl-field-background-disabled);
6401
+ cursor: not-allowed;
6402
+ }
6403
+
6404
+ .MoneyField[data-readonly] .MoneyFieldInput {
6405
+ cursor: default;
6406
+ }
6407
+
6408
+ /* The palette is the one on the field. An ancestor data-color does not recolor a balance. */
6409
+ .MoneyField[data-negative][data-color] .MoneyFieldInput {
6410
+ color: var(--sl-scope-fg);
6411
+ }
6412
+
6413
+ .MoneyField[data-scrubbing] .MoneyFieldInput {
6414
+ cursor: ns-resize;
6415
+ }
6416
+
6417
+ /* The sign toggle is for coarse pointers: an iOS decimal keypad has no minus key. */
6418
+ .MoneyFieldSign {
6419
+ display: none;
6420
+ align-self: center;
6421
+ flex: none;
6422
+ }
6423
+
6424
+ @media (pointer: coarse) {
6425
+ .MoneyFieldSign {
6426
+ display: inline-flex;
6427
+ }
6428
+ }
6429
+
6430
+ /* ============================================
6431
+ AFFIX
6432
+ ============================================ */
6433
+
6434
+ .MoneyFieldAffix {
6435
+ display: inline-flex;
6436
+ align-items: center;
6437
+ flex: none;
6438
+ padding-inline: var(--sl-control-padding-inline);
6439
+ color: var(--sl-field-affix-color);
6440
+ user-select: none;
6441
+ }
6442
+
6443
+ .MoneyField[data-size='xs'] .MoneyFieldAffix {
6444
+ padding-inline: var(--sl-control-padding-inline-xs);
6445
+ }
6446
+
6447
+ .MoneyField[data-size='sm'] .MoneyFieldAffix {
6448
+ padding-inline: var(--sl-control-padding-inline-sm);
6449
+ }
6450
+
6451
+ .MoneyField[data-size='lg'] .MoneyFieldAffix {
6452
+ padding-inline: var(--sl-control-padding-inline-lg);
6453
+ }
6454
+
6455
+ /* ============================================
6456
+ CURRENCY SELECT
6457
+ ============================================ */
6458
+
6459
+ .MoneyFieldCurrency {
6460
+ display: flex;
6461
+ align-self: stretch;
6462
+ flex: none;
6463
+ }
6464
+
6465
+ .MoneyFieldCurrencyTrigger {
6466
+ display: inline-flex;
6467
+ align-items: center;
6468
+ align-self: stretch;
6469
+ flex: none;
6470
+ gap: var(--sl-space-1);
6471
+ height: auto;
6472
+ min-height: 0;
6473
+ padding-inline: var(--sl-control-padding-inline);
6474
+ border: 0;
6475
+ border-radius: 0;
6476
+ background: transparent;
6477
+ box-shadow: none;
6478
+ color: var(--sl-field-affix-color);
6479
+ }
6480
+
6481
+ .MoneyField[data-size='xs'] .MoneyFieldCurrencyTrigger {
6482
+ padding-inline: var(--sl-control-padding-inline-xs);
6483
+ }
6484
+
6485
+ .MoneyField[data-size='sm'] .MoneyFieldCurrencyTrigger {
6486
+ padding-inline: var(--sl-control-padding-inline-sm);
6487
+ }
6488
+
6489
+ .MoneyField[data-size='lg'] .MoneyFieldCurrencyTrigger {
6490
+ padding-inline: var(--sl-control-padding-inline-lg);
6491
+ }
6492
+
6493
+ .MoneyField[data-affix='start'] .MoneyFieldCurrency {
6494
+ border-inline-end: var(--sl-field-border-width) solid var(--sl-field-border-color);
6495
+ }
6496
+
6497
+ .MoneyField[data-affix='end'] .MoneyFieldCurrency {
6498
+ border-inline-start: var(--sl-field-border-width) solid var(--sl-field-border-color);
6499
+ }
6500
+
6501
+ .MoneyFieldCurrencyTrigger:hover,
6502
+ .MoneyFieldCurrencyTrigger:focus,
6503
+ .MoneyFieldCurrencyTrigger[data-popup-open],
6504
+ .MoneyFieldCurrencyTrigger[aria-expanded='true'] {
6505
+ border-color: transparent;
6506
+ background: transparent;
6507
+ box-shadow: none;
6508
+ color: var(--sl-text-primary);
6509
+ }
6510
+
6511
+ /* The group halo says the field is focused. This says the picker, not the amount, has the caret. */
6512
+ .MoneyFieldCurrencyTrigger:focus-visible {
6513
+ outline: var(--sl-focus-outline);
6514
+ outline-offset: var(--sl-focus-outline-offset-inset);
6515
+ }
6516
+
6517
+ /* The picker is its own field, so it does not take the amount's label. */
6518
+ .MoneyFieldCurrencyField,
6519
+ .MoneyFieldGroup .ComboboxRoot {
6520
+ display: contents;
6521
+ }
6522
+
6523
+ .MoneyFieldCurrencyIcon {
6524
+ width: var(--sl-icon-size-base);
6525
+ height: var(--sl-icon-size-base);
6526
+ font-size: var(--sl-icon-size-base);
6527
+ }
6528
+
6529
+ .MoneyField[data-size='xs'] .MoneyFieldCurrencyIcon {
6530
+ width: var(--sl-icon-size-minimize);
6531
+ height: var(--sl-icon-size-minimize);
6532
+ font-size: var(--sl-icon-size-minimize);
6533
+ }
6534
+
6535
+ .MoneyField[data-size='sm'] .MoneyFieldCurrencyIcon {
6536
+ width: var(--sl-icon-size-condense);
6537
+ height: var(--sl-icon-size-condense);
6538
+ font-size: var(--sl-icon-size-condense);
6539
+ }
6540
+
6541
+ .MoneyField[data-size='lg'] .MoneyFieldCurrencyIcon {
6542
+ width: var(--sl-icon-size-magnify);
6543
+ height: var(--sl-icon-size-magnify);
6544
+ font-size: var(--sl-icon-size-magnify);
6545
+ }
6546
+
6547
+ .MoneyFieldCurrencyPopup {
6548
+ min-inline-size: var(--sl-money-field-picker-min-inline-size);
6549
+ }
6550
+
6551
+ .MoneyFieldCurrencyItem {
6552
+ display: flex;
6553
+ align-items: center;
6554
+ justify-content: space-between;
6555
+ gap: var(--sl-space-4);
6556
+ width: 100%;
6557
+ }
6558
+
6559
+ .MoneyFieldCurrencySymbol {
6560
+ color: var(--sl-text-secondary);
6561
+ }
6562
+
6563
+ .MoneyFieldCurrencyPopup .ComboboxInput {
6564
+ font-family: var(--sl-font-body-base-font-family);
6565
+ font-size: var(--sl-font-body-base-font-size);
6566
+ font-weight: var(--sl-font-body-base-font-weight);
6567
+ line-height: var(--sl-font-body-base-line-height);
6568
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
6569
+ }
6570
+
6571
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6572
+ /* ListDetail
6573
+ *
6574
+ * The detail of one item, next to its list. Not a Base UI part. It is a Splitter
6575
+ * when this element is at least list-detail.split-min-width wide, measured on the
6576
+ * element itself so it still works inside another panel. Narrower, the detail is
6577
+ * the existing Drawer (the default) or it replaces the list, which stays mounted
6578
+ * and hidden so its scroll position survives Back.
6579
+ *
6580
+ * The list stays in the splitter's first panel whether the detail is open, closed,
6581
+ * or in a drawer, so its scroll survives. The detail is portaled into a node the
6582
+ * component created, and that node moves. The list sits on the page surface. The
6583
+ * detail sits on surface.raised: a pane
6584
+ * beside the list, one step off the page, with the splitter line as the only
6585
+ * divider. A modal surface would make the pane look like a dialog stuck in the
6586
+ * layout. Drawer mode does not restyle that; it uses the Drawer's own modal
6587
+ * surface, title and Close, so it matches every other drawer.
6588
+ *
6589
+ * The header title is text-title-condense. title-amplify is for a dialog or a
6590
+ * drawer, a layer over the page. A pane heading shares the view with the list,
6591
+ * so the condensed title fits the row. Close is a quiet icon-only Button: a
6592
+ * text Close would compete with the title and the actions in a short header.
6593
+ * Page mode puts Back, icon and word, where Close was.
6594
+ *
6595
+ * Focus moves to the heading when the detail opens, and back to the row when it
6596
+ * closes. Changing the title because another row was picked does not move focus.
6597
+ * Escape closes only when it bubbles out of the detail, so an open menu handles
6598
+ * it first. Nothing listens on window. Page changes are announced by that focus
6599
+ * move; there is no live region.
6600
+ *
6601
+ * data-layout is split, drawer or page. data-open is set while the detail is open.
6602
+ */
6603
+
6604
+ .ListDetail {
6605
+ display: flex;
6606
+ flex-direction: column;
6607
+ width: 100%;
6608
+ height: 100%;
6609
+ min-width: 0;
6610
+ min-height: 0;
6611
+ }
6612
+
6613
+ .ListDetailHost,
6614
+ .ListDetailSlot,
6615
+ .ListDetailSplit,
6616
+ .ListDetailList,
6617
+ .ListDetailDetail {
6618
+ display: flex;
6619
+ flex-direction: column;
6620
+ min-width: 0;
6621
+ min-height: 0;
6622
+ height: 100%;
6623
+ flex: 1;
6624
+ }
6625
+
6626
+ .ListDetailList {
6627
+ overflow: auto;
6628
+ background: transparent;
6629
+ }
6630
+
6631
+ .ListDetail[data-layout='split'],
6632
+ .ListDetail[data-layout='drawer'],
6633
+ .ListDetail[data-layout='page'] {
6634
+ min-width: 0;
6635
+ }
6636
+
6637
+ .ListDetail[data-open] .ListDetailList {
6638
+ min-height: 0;
6639
+ }
6640
+
6641
+ .ListDetailDetail[data-layout='split'],
6642
+ .ListDetailDetail[data-layout='page'] {
6643
+ background: var(--sl-surface-raised);
6644
+ }
6645
+
6646
+ .ListDetailDetail[data-layout='drawer'] {
6647
+ background: transparent;
6648
+ }
6649
+
6650
+ .DrawerPopup .ListDetailHeader,
6651
+ .ListDetailDetail[data-layout='drawer'] .ListDetailBody {
6652
+ padding: 0;
6653
+ }
6654
+
6655
+ .ListDetailHeader {
6656
+ display: flex;
6657
+ align-items: center;
6658
+ gap: var(--sl-list-detail-header-gap);
6659
+ padding: var(--sl-list-detail-header-padding);
6660
+ flex: none;
6661
+ }
6662
+
6663
+ .ListDetailTitle {
6664
+ font-family: var(--sl-font-title-condense-font-family);
6665
+ font-size: var(--sl-font-title-condense-font-size);
6666
+ font-weight: var(--sl-font-title-condense-font-weight);
6667
+ line-height: var(--sl-font-title-condense-line-height);
6668
+ letter-spacing: var(--sl-font-title-condense-letter-spacing);
6669
+ margin: 0;
6670
+ flex: 1;
6671
+ min-width: 0;
6672
+ }
6673
+
6674
+ .ListDetailHeader .DrawerTitle {
6675
+ flex: 1;
6676
+ min-width: 0;
6677
+ }
6678
+
6679
+ .ListDetailActions {
6680
+ display: flex;
6681
+ align-items: center;
6682
+ gap: var(--sl-list-detail-header-gap);
6683
+ flex: none;
6684
+ }
6685
+
6686
+ .ListDetailBody {
6687
+ flex: 1;
6688
+ min-height: 0;
6689
+ overflow: auto;
6690
+ padding-inline: var(--sl-list-detail-header-padding);
6691
+ padding-block-end: var(--sl-list-detail-header-padding);
6692
+ }
6693
+
6694
+ .ListDetail[data-layout='drawer'] .ListDetailDetail {
6695
+ background: transparent;
6696
+ }
6697
+
6698
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6699
+ /* Splitter
6700
+ *
6701
+ * Two or more panels and a handle between them. Not a Base UI part. It follows the
6702
+ * window splitter pattern: the handle is a separator you drag or move with the arrow
6703
+ * keys. Each panel's size is --sl-splitter-panel-size, so a drag can update the line
6704
+ * without rendering the tree again. The parent gives the root its height.
6705
+ *
6706
+ * One panel has no size and fills what the others leave (the last panel, when every
6707
+ * panel has a size). Px and percent mix, so a workstation can pin its sides in pixels
6708
+ * while a list keeps a percent.
6709
+ *
6710
+ * Arrow keys move one key step, 5% of the splitter; Shift uses the larger step.
6711
+ * Home and End jump to that panel's min and max. Enter collapses a collapsible panel
6712
+ * and restores the size it had. Double-click resets to the default size. In RTL,
6713
+ * Left and Right swap. A panel collapsed to nothing is hidden, so its contents leave
6714
+ * the tab order.
6715
+ *
6716
+ * data-orientation is on the root, the panel and the handle. data-dragging is on the
6717
+ * root and the handle while the pointer is down. data-collapsed is on a collapsed
6718
+ * panel and on the handle that resizes it. data-disabled is on the handle. data-grip
6719
+ * draws the grip. data-fill marks the panel that takes the leftover space.
6720
+ *
6721
+ * The line is one stroke. The part you grab sits on the next panel's inline-start,
6722
+ * not centered, so it does not cover the previous panel's scrollbar. A fine pointer
6723
+ * gets a11y.min-target (24px). A coarse pointer gets the 44px touch target. The
6724
+ * focus ring is drawn on that grab area: a ring around the 1px line reads as a
6725
+ * second hairline. Collapse animates with duration.normal. A drag does not animate.
6726
+ * Reduced motion is the shared reset, which finishes every transition at once.
6727
+ */
6728
+
6729
+ .Splitter {
6730
+ display: flex;
6731
+ width: 100%;
6732
+ height: 100%;
6733
+ min-width: 0;
6734
+ min-height: 0;
6735
+ }
6736
+
6737
+ .Splitter[data-orientation='horizontal'] {
6738
+ flex-direction: row;
6739
+ }
6740
+
6741
+ .Splitter[data-orientation='vertical'] {
6742
+ flex-direction: column;
6743
+ }
6744
+
6745
+ .Splitter[data-dragging] .SplitterPanel {
6746
+ transition: none;
6747
+ }
6748
+
6749
+ .SplitterPanel {
6750
+ --sl-splitter-panel-size: auto;
6751
+ position: relative;
6752
+ box-sizing: border-box;
6753
+ min-width: 0;
6754
+ min-height: 0;
6755
+ overflow: hidden;
6756
+ flex: 0 0 var(--sl-splitter-panel-size);
6757
+ transition:
6758
+ flex-basis var(--sl-duration-normal) var(--sl-easing-default),
6759
+ width var(--sl-duration-normal) var(--sl-easing-default),
6760
+ height var(--sl-duration-normal) var(--sl-easing-default);
6761
+ }
6762
+
6763
+ .SplitterPanel[data-orientation='horizontal'] {
6764
+ width: var(--sl-splitter-panel-size);
6765
+ height: auto;
6766
+ }
6767
+
6768
+ .SplitterPanel[data-orientation='vertical'] {
6769
+ height: var(--sl-splitter-panel-size);
6770
+ width: auto;
6771
+ }
6772
+
6773
+ .SplitterPanel[data-orientation='horizontal'][data-fill]:not([data-collapsed]) {
6774
+ flex: 1 1 auto;
6775
+ width: auto;
6776
+ }
6777
+
6778
+ .SplitterPanel[data-orientation='vertical'][data-fill]:not([data-collapsed]) {
6779
+ flex: 1 1 auto;
6780
+ height: auto;
6781
+ }
6782
+
6783
+ /* A ScrollArea thumb still stacks above the grab area, for a bar that lives in the
6784
+ next panel, under the part of the hit area that crosses the line. */
6785
+ .SplitterPanel .ScrollAreaScrollbar {
6786
+ z-index: 2;
6787
+ }
6788
+
6789
+ .SplitterHandle {
6790
+ position: relative;
6791
+ flex: none;
6792
+ box-sizing: border-box;
6793
+ border: 0;
6794
+ padding: 0;
6795
+ background: transparent;
6796
+ touch-action: none;
6797
+ color: var(--sl-border-default);
6798
+ }
6799
+
6800
+ .SplitterHandle[data-orientation='horizontal'] {
6801
+ width: var(--sl-splitter-handle-size);
6802
+ height: auto;
6803
+ align-self: stretch;
6804
+ cursor: col-resize;
6805
+ }
6806
+
6807
+ .SplitterHandle[data-orientation='vertical'] {
6808
+ height: var(--sl-splitter-handle-size);
6809
+ width: auto;
6810
+ align-self: stretch;
6811
+ cursor: row-resize;
6812
+ }
6813
+
6814
+ .SplitterHandle::before,
6815
+ .SplitterHandle::after {
6816
+ content: '';
6817
+ position: absolute;
6818
+ }
6819
+
6820
+ .SplitterHandle::before {
6821
+ left: 50%;
6822
+ top: 50%;
6823
+ transform: translate(-50%, -50%);
6824
+ }
6825
+
6826
+ .SplitterHandle[data-orientation='horizontal']::before {
6827
+ width: var(--sl-splitter-handle-size);
6828
+ height: 100%;
6829
+ background: var(--sl-border-default);
6830
+ }
6831
+
6832
+ .SplitterHandle[data-orientation='vertical']::before {
6833
+ height: var(--sl-splitter-handle-size);
6834
+ width: 100%;
6835
+ background: var(--sl-border-default);
6836
+ }
6837
+
6838
+ /* The grab area starts on the line and extends into the next panel. The previous
6839
+ panel keeps its scrollbar, which sits on its inline-end, against this line. */
6840
+ .SplitterHandle[data-orientation='horizontal']::after {
6841
+ inset-inline-start: 0;
6842
+ top: 0;
6843
+ bottom: 0;
6844
+ width: var(--sl-a11y-min-target);
6845
+ z-index: 1;
6846
+ }
6847
+
6848
+ .SplitterHandle[data-orientation='vertical']::after {
6849
+ inset-block-start: 0;
6850
+ left: 0;
6851
+ right: 0;
6852
+ height: var(--sl-a11y-min-target);
6853
+ z-index: 1;
6854
+ }
6855
+
6856
+ @media (pointer: coarse) {
6857
+ .SplitterHandle[data-orientation='horizontal']::after {
6858
+ width: var(--sl-splitter-handle-hit-size);
6859
+ }
6860
+
6861
+ .SplitterHandle[data-orientation='vertical']::after {
6862
+ height: var(--sl-splitter-handle-hit-size);
6863
+ }
6864
+ }
6865
+
6866
+ .SplitterHandle:hover::before,
6867
+ .SplitterHandle[data-dragging]::before,
6868
+ .SplitterHandle[data-collapsed]::before {
6869
+ background: var(--sl-border-strong);
6870
+ }
6871
+
6872
+ /* The dot edge (45% to 50%) is the shape of the grip, not a size token. */
6873
+ /* The dots sit on the line, at the start of the grab area, not in its middle. */
6874
+ .SplitterHandle[data-orientation='horizontal'][data-grip]::after {
6875
+ background:
6876
+ 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,
6877
+ 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,
6878
+ 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;
6879
+ }
6880
+
6881
+ .SplitterHandle[data-orientation='vertical'][data-grip]::after {
6882
+ background:
6883
+ 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,
6884
+ 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,
6885
+ 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;
6886
+ }
6887
+
6888
+ .SplitterHandle:focus {
6889
+ outline: none;
6890
+ }
6891
+
6892
+ .SplitterHandle:focus-visible::after {
6893
+ outline: var(--sl-focus-outline);
6894
+ outline-offset: var(--sl-focus-outline-offset);
6895
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
6896
+ }
6897
+
6898
+ .SplitterHandle[data-disabled] {
6899
+ cursor: not-allowed;
6900
+ }
6901
+
6902
+ .SplitterHandle[data-disabled]::before {
6903
+ background: var(--sl-border-default);
6904
+ }
6905
+
6906
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
6907
+ /* EmptyState
6908
+ *
6909
+ * The block a page, pane, table, list or popup shows when it has nothing to show.
6910
+ * One look for every kind. data-kind only picks the media tone and, in the component,
6911
+ * the default icon and whether the block is announced. Sizes are empty.*
6912
+ * (tokens/semantic/empty.json). No border and no fill: the container provides those.
6913
+ *
6914
+ * The circle uses the subtle emphasis level (--sl-e-bg, --sl-e-fg), the same variables
6915
+ * Badge uses. data-status on the media recolors it. A parent data-color does too:
6916
+ * the subtle chrome pin skips this circle when a color scope is on an ancestor
6917
+ * (Badge keeps the pin). A brand pair re-points fill and text, not that chrome
6918
+ * scope. The circle stays chrome subtle inside a pair, the same as Badge, so a
6919
+ * pair does not get its own selector. High contrast and the vision themes come
6920
+ * with those variables. The title stays
6921
+ * text-primary and the description text-secondary: an error's title is not red,
6922
+ * because a sentence has to stay readable. Neutral kinds use the chrome palette,
6923
+ * which is what subtle resolves to when no status is set.
6924
+ *
6925
+ * Text is a whole style per size, not a font-size on its own. Compact is a table
6926
+ * row or a popup, so the title is subtitle-condense (bold, the row's size) and the
6927
+ * description is body-condense. Standard is a pane: title-condense, the section
6928
+ * heading, with body-base under it. Spacious is a page: title-magnify, the next
6929
+ * title up, still body-base so the sentence doesn't grow with the heading.
6930
+ * Unselected is the quiet pane beside a list, so it drops the circle, the icon is
6931
+ * text-tertiary, and the title steps down one tier: subtitle-minimize where the
6932
+ * others use a condense style (there is no title at minimize), and title-condense
6933
+ * where the others use title-magnify.
6934
+ *
6935
+ * Compact is a row (icon, text, actions) centered across the cell. Standard and
6936
+ * spacious are a column. They take margin-block: auto so a flex or grid column
6937
+ * centers them in the leftover space; in normal flow that margin is zero, so a
6938
+ * page that isn't a column doesn't grow a hole. There is no data-fill attribute.
6939
+ *
6940
+ * The icon for unselected is left_click: the pane is waiting for a choice in the
6941
+ * list beside it, which an empty inbox would not say.
6942
+ *
6943
+ * A popup's empty slot already pads a plain sentence (popup-empty). When the child
6944
+ * is an EmptyState, that padding drops so the two don't add. Menu.Empty has no
6945
+ * popup-empty padding of its own, so it needs nothing here.
6946
+ */
6947
+
6948
+ /* ============================================
6949
+ ROOT
6950
+ ============================================ */
6951
+
6952
+ .EmptyState {
6953
+ box-sizing: border-box;
6954
+ display: flex;
6955
+ flex-direction: column;
6956
+ align-items: center;
6957
+ justify-content: center;
6958
+ gap: var(--sl-empty-gap-standard);
6959
+ width: 100%;
6960
+ padding-block: var(--sl-empty-padding-block-standard);
6961
+ padding-inline: var(--sl-empty-padding-inline-standard);
6962
+ color: var(--sl-text-primary);
6963
+ text-align: center;
6964
+ }
6965
+
6966
+ /* ============================================
6967
+ MEDIA
6968
+ ============================================ */
6969
+
6970
+ .EmptyStateMedia {
6971
+ display: inline-flex;
6972
+ flex-shrink: 0;
6973
+ align-items: center;
6974
+ justify-content: center;
6975
+ width: var(--sl-empty-media-size-standard);
6976
+ height: var(--sl-empty-media-size-standard);
6977
+ border-radius: var(--sl-radius-pill);
6978
+ background: var(--sl-e-bg);
6979
+ color: var(--sl-e-fg);
6980
+ }
6981
+
6982
+ .EmptyStateMedia:not([data-custom]) .material-symbols-outlined,
6983
+ .EmptyStateMedia:not([data-custom]) svg {
6984
+ width: var(--sl-icon-size-magnify);
6985
+ height: var(--sl-icon-size-magnify);
6986
+ font-size: var(--sl-icon-size-magnify);
6987
+ line-height: 1;
6988
+ }
6989
+
6990
+ /* An illustration the app passed in. No circle and no tint. */
6991
+ .EmptyStateMedia[data-custom] {
6992
+ width: auto;
6993
+ height: auto;
6994
+ background: none;
6995
+ color: inherit;
6996
+ }
6997
+
6998
+ /* ============================================
6999
+ TEXT
7000
+ ============================================ */
7001
+
7002
+ .EmptyStateText {
7003
+ display: flex;
7004
+ flex-direction: column;
7005
+ align-items: center;
7006
+ gap: var(--sl-empty-text-gap-standard);
7007
+ min-width: 0;
7008
+ max-width: var(--sl-empty-description-max-width);
7009
+ }
7010
+
7011
+ .EmptyStateTitle {
7012
+ font-family: var(--sl-font-title-condense-font-family);
7013
+ font-size: var(--sl-font-title-condense-font-size);
7014
+ font-weight: var(--sl-font-title-condense-font-weight);
7015
+ line-height: var(--sl-font-title-condense-line-height);
7016
+ letter-spacing: var(--sl-font-title-condense-letter-spacing);
7017
+ margin: 0;
7018
+ max-width: 100%;
7019
+ color: var(--sl-text-primary);
7020
+ }
7021
+
7022
+ .EmptyStateDescription {
7023
+ font-family: var(--sl-font-body-base-font-family);
7024
+ font-size: var(--sl-font-body-base-font-size);
7025
+ font-weight: var(--sl-font-body-base-font-weight);
7026
+ line-height: var(--sl-font-body-base-line-height);
7027
+ letter-spacing: var(--sl-font-body-base-letter-spacing);
7028
+ margin: 0;
7029
+ max-width: 100%;
7030
+ color: var(--sl-text-secondary);
7031
+ }
7032
+
7033
+ /* ============================================
7034
+ ACTIONS
7035
+ ============================================ */
7036
+
7037
+ .EmptyStateActions {
7038
+ display: flex;
7039
+ flex-wrap: wrap;
7040
+ align-items: center;
7041
+ justify-content: center;
7042
+ gap: var(--sl-empty-actions-gap);
7043
+ }
7044
+
7045
+ /* ============================================
7046
+ SIZES
7047
+ ============================================ */
7048
+
7049
+ .EmptyState[data-size='compact'] {
7050
+ flex-direction: row;
7051
+ flex-wrap: wrap;
7052
+ gap: var(--sl-empty-gap-compact);
7053
+ padding-block: var(--sl-empty-padding-block-compact);
7054
+ padding-inline: var(--sl-empty-padding-inline-compact);
7055
+ }
7056
+
7057
+ .EmptyState[data-size='compact'] .EmptyStateText {
7058
+ gap: var(--sl-empty-text-gap-compact);
7059
+ }
7060
+
7061
+ .EmptyState[data-size='compact'] .EmptyStateTitle {
7062
+ font-family: var(--sl-font-subtitle-condense-font-family);
7063
+ font-size: var(--sl-font-subtitle-condense-font-size);
7064
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
7065
+ line-height: var(--sl-font-subtitle-condense-line-height);
7066
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
7067
+ }
7068
+
7069
+ .EmptyState[data-size='compact'] .EmptyStateDescription {
7070
+ font-family: var(--sl-font-body-condense-font-family);
7071
+ font-size: var(--sl-font-body-condense-font-size);
7072
+ font-weight: var(--sl-font-body-condense-font-weight);
7073
+ line-height: var(--sl-font-body-condense-line-height);
7074
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7075
+ }
7076
+
7077
+ /* Icon only. The tone stays on the glyph, so an error is still an error. */
7078
+ .EmptyState[data-size='compact'] .EmptyStateMedia {
7079
+ width: auto;
7080
+ height: auto;
7081
+ background: none;
7082
+ }
7083
+
7084
+ .EmptyState[data-size='compact'] .EmptyStateMedia:not([data-custom]) .material-symbols-outlined,
7085
+ .EmptyState[data-size='compact'] .EmptyStateMedia:not([data-custom]) svg {
7086
+ width: var(--sl-icon-size-condense);
7087
+ height: var(--sl-icon-size-condense);
7088
+ font-size: var(--sl-icon-size-condense);
7089
+ }
7090
+
7091
+ .EmptyState[data-size='spacious'] {
7092
+ gap: var(--sl-empty-gap-spacious);
7093
+ padding-block: var(--sl-empty-padding-block-spacious);
7094
+ padding-inline: var(--sl-empty-padding-inline-spacious);
7095
+ }
7096
+
7097
+ .EmptyState[data-size='spacious'] .EmptyStateText {
7098
+ gap: var(--sl-empty-text-gap-spacious);
7099
+ }
7100
+
7101
+ .EmptyState[data-size='spacious'] .EmptyStateTitle {
7102
+ font-family: var(--sl-font-title-magnify-font-family);
7103
+ font-size: var(--sl-font-title-magnify-font-size);
7104
+ font-weight: var(--sl-font-title-magnify-font-weight);
7105
+ line-height: var(--sl-font-title-magnify-line-height);
7106
+ letter-spacing: var(--sl-font-title-magnify-letter-spacing);
7107
+ }
7108
+
7109
+ .EmptyState[data-size='spacious'] .EmptyStateMedia {
7110
+ width: var(--sl-empty-media-size-spacious);
7111
+ height: var(--sl-empty-media-size-spacious);
7112
+ }
7113
+
7114
+ .EmptyState[data-size='spacious'] .EmptyStateMedia:not([data-custom]) .material-symbols-outlined,
7115
+ .EmptyState[data-size='spacious'] .EmptyStateMedia:not([data-custom]) svg {
7116
+ width: var(--sl-icon-size-maximize);
7117
+ height: var(--sl-icon-size-maximize);
7118
+ font-size: var(--sl-icon-size-maximize);
7119
+ }
7120
+
7121
+ /* ============================================
7122
+ PLACES
7123
+ ============================================ */
7124
+
7125
+ /* A flex or grid column centers the block in the space left over. */
7126
+ .EmptyState:is([data-size='standard'], [data-size='spacious']) {
7127
+ margin-block: auto;
7128
+ }
7129
+
7130
+ /* The detail pane before a row is picked. Quieter than the list beside it. */
7131
+ .EmptyState[data-kind='unselected'] .EmptyStateMedia {
7132
+ width: auto;
7133
+ height: auto;
7134
+ background: none;
7135
+ color: var(--sl-text-tertiary);
7136
+ }
7137
+
7138
+ .EmptyState[data-kind='unselected'][data-size='compact'] .EmptyStateTitle,
7139
+ .EmptyState[data-kind='unselected'][data-size='standard'] .EmptyStateTitle {
7140
+ font-family: var(--sl-font-subtitle-minimize-font-family);
7141
+ font-size: var(--sl-font-subtitle-minimize-font-size);
7142
+ font-weight: var(--sl-font-subtitle-minimize-font-weight);
7143
+ line-height: var(--sl-font-subtitle-minimize-line-height);
7144
+ letter-spacing: var(--sl-font-subtitle-minimize-letter-spacing);
7145
+ }
7146
+
7147
+ .EmptyState[data-kind='unselected'][data-size='spacious'] .EmptyStateTitle {
7148
+ font-family: var(--sl-font-title-condense-font-family);
7149
+ font-size: var(--sl-font-title-condense-font-size);
7150
+ font-weight: var(--sl-font-title-condense-font-weight);
7151
+ line-height: var(--sl-font-title-condense-line-height);
7152
+ letter-spacing: var(--sl-font-title-condense-letter-spacing);
7153
+ }
7154
+
7155
+ /* The popup slot pads a plain sentence. An EmptyState brings its own padding. */
7156
+ .ComboboxEmpty:has(> .EmptyState),
7157
+ .AutocompleteEmpty:has(> .EmptyState) {
7158
+ padding: 0;
7159
+ color: inherit;
7160
+ }
7161
+
7162
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7163
+ /* Table - Mojave Theme
7164
+ *
7165
+ * Base UI has no table, so this styles the native <table class="Table"> elements with the
7166
+ * table concept (tokens/semantic/table.json), the same tokens the AG Grid themes read: a small
7167
+ * hand-built table and a full grid look alike. Rows answer to aria-selected="true",
7168
+ * aria-current="true" (the row whose detail is open) or data-selected; cells take
7169
+ * data-align="end" for numbers.
7170
+ *
7171
+ * An empty body keeps the header and the column widths: one cell spanning the columns,
7172
+ * `<tr><td data-empty colSpan={n}><EmptyState size="compact" … /></td></tr>`. A cell with
7173
+ * only text still uses this rule's padding. A cell whose child is an EmptyState lets the
7174
+ * empty state pad itself. The empty row does not take the row hover.
7175
+ */
7176
+
7177
+ .Table {
7178
+ font-family: var(--sl-font-body-condense-font-family);
7179
+ font-size: var(--sl-font-body-condense-font-size);
7180
+ font-weight: var(--sl-font-body-condense-font-weight);
7181
+ line-height: var(--sl-font-body-condense-line-height);
7182
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7183
+ box-sizing: border-box;
7184
+ width: 100%;
7185
+ border-collapse: separate;
7186
+ border-spacing: 0;
7187
+ background: var(--sl-table-background);
7188
+ color: var(--sl-table-color);
7189
+ border: var(--sl-stroke-default) solid var(--sl-table-border-color);
7190
+ border-radius: var(--sl-table-radius);
7191
+ overflow: hidden;
7192
+ font-variant-numeric: tabular-nums;
7193
+ }
7194
+
7195
+ .Table caption {
7196
+ font-family: var(--sl-font-body-condense-font-family);
7197
+ font-size: var(--sl-font-body-condense-font-size);
7198
+ font-weight: var(--sl-font-body-condense-font-weight);
7199
+ line-height: var(--sl-font-body-condense-line-height);
7200
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7201
+ caption-side: bottom;
7202
+ padding-block: var(--sl-space-2);
7203
+ color: var(--sl-table-subtle-color);
7204
+ text-align: start;
7205
+ }
7206
+
7207
+ /* Header: the tray band, a little taller than the rows */
7208
+ .Table th {
7209
+ font-family: var(--sl-font-subtitle-condense-font-family);
7210
+ font-size: var(--sl-font-subtitle-condense-font-size);
7211
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
7212
+ line-height: var(--sl-font-subtitle-condense-line-height);
7213
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
7214
+ height: var(--sl-table-header-height);
7215
+ padding-block: 0;
7216
+ padding-inline: var(--sl-table-cell-padding-inline);
7217
+ background: var(--sl-table-header-background);
7218
+ color: var(--sl-table-header-color);
7219
+ text-align: start;
7220
+ vertical-align: middle;
7221
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-border-color);
7222
+ }
7223
+
7224
+ /* A header that sorts: aria-sort on the th */
7225
+ .Table th[aria-sort] {
7226
+ cursor: pointer;
7227
+ transition: background-color var(--sl-duration-fast) var(--sl-easing-default);
7228
+ }
7229
+
7230
+ .Table th[aria-sort]:hover {
7231
+ background: var(--sl-table-header-background-hover);
7232
+ }
7233
+
7234
+ /* Body cells */
7235
+ .Table td {
7236
+ height: var(--sl-table-row-height);
7237
+ padding-block: 0;
7238
+ padding-inline: var(--sl-table-cell-padding-inline);
7239
+ vertical-align: middle;
7240
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
7241
+ }
7242
+
7243
+ .Table tbody tr:last-child td,
7244
+ .Table tbody:last-child tr:last-child td {
7245
+ border-bottom: none;
7246
+ }
7247
+
7248
+ /* A row header (th in tbody) reads like a cell, in the header's weight */
7249
+ .Table tbody th {
7250
+ background: transparent;
7251
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
7252
+ }
7253
+
7254
+ /* Numbers and amounts: right-aligned so digits line up */
7255
+ .Table [data-align='end'] {
7256
+ text-align: end;
7257
+ }
7258
+
7259
+ .Table [data-align='center'] {
7260
+ text-align: center;
7261
+ }
7262
+
7263
+ /* Secondary text in a cell */
7264
+ .Table [data-subtle] {
7265
+ color: var(--sl-table-subtle-color);
7266
+ }
7267
+
7268
+ /* Hover and selection: the same tints as list items */
7269
+ @media (hover: hover) {
7270
+ .Table tbody tr:hover > * {
7271
+ background: var(--sl-table-row-hover);
7272
+ color: var(--sl-item-color-hover);
7273
+ }
7274
+ }
7275
+
7276
+ .Table tbody tr:is([aria-selected='true'], [data-selected]) > * {
7277
+ background: var(--sl-table-row-selected);
7278
+ color: var(--sl-item-color-selected);
7279
+ }
7280
+
7281
+ /* The open row keeps a fill, and a bar on the inline start so it is not only a color. */
7282
+ .Table tbody tr[aria-current='true'] > * {
7283
+ background: var(--sl-table-row-current);
7284
+ color: var(--sl-table-color);
7285
+ box-shadow: inset var(--sl-stroke-strong) 0 0 0 var(--sl-border-accent);
7286
+ }
7287
+
7288
+ [dir='rtl'] .Table tbody tr[aria-current='true'] > * {
7289
+ box-shadow: inset calc(var(--sl-stroke-strong) * -1) 0 0 0 var(--sl-border-accent);
7290
+ }
7291
+
7292
+ /* Footer: totals on the tray band */
7293
+ .Table tfoot td {
7294
+ font-family: var(--sl-font-subtitle-condense-font-family);
7295
+ font-size: var(--sl-font-subtitle-condense-font-size);
7296
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
7297
+ line-height: var(--sl-font-subtitle-condense-line-height);
7298
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
7299
+ background: var(--sl-table-header-background);
7300
+ border-top: var(--sl-stroke-default) solid var(--sl-table-border-color);
7301
+ border-bottom: none;
7302
+ }
7303
+
7304
+ /* A header that stays put while the body scrolls (the table's wrapper scrolls) */
7305
+ .Table[data-sticky-header] thead th {
7306
+ position: sticky;
7307
+ top: 0;
7308
+ z-index: var(--sl-z-index-docked);
7309
+ }
7310
+
7311
+ /* Empty state: one cell spanning the columns. Plain text keeps the old padding.
7312
+ An EmptyState brings its own, and its title stays the normal text color on hover. */
7313
+ .Table td[data-empty] {
7314
+ height: auto;
7315
+ padding-block: var(--sl-space-10);
7316
+ color: var(--sl-text-tertiary);
7317
+ text-align: center;
7318
+ }
7319
+
7320
+ .Table td[data-empty]:has(> .EmptyState) {
7321
+ padding: 0;
7322
+ color: inherit;
7323
+ }
7324
+
7325
+ .Table tbody tr:has(> td[data-empty]):hover > * {
7326
+ background: transparent;
7327
+ color: var(--sl-text-tertiary);
7328
+ }
7329
+
7330
+ .Table tbody tr:has(> td[data-empty] > .EmptyState):hover > * {
7331
+ color: inherit;
7332
+ }
7333
+
7334
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7335
+ /* Collection
7336
+ *
7337
+ * DataTable, DataList, the toolbar and the pagination, in one place so the two views
7338
+ * share the table concept. Sections: toolbar, table additions, groups, list, pagination, sizes.
7339
+ * Each section is its own file so the design system can name the part. This file brings them in.
7340
+ *
7341
+ * The selection bar replaces the trailing controls (filters, sort, clear, actions) and leaves
7342
+ * the tabs and the search where they are, so selecting rows does not grow the toolbar.
7343
+ */
7344
+
7345
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7346
+ /* Collection toolbar
7347
+ *
7348
+ * The wrap follows the toolbar's own width, not the window: a table in a narrow pane wraps
7349
+ * even when the page is wide. Search takes the full width first. Filters wrap under it.
7350
+ * A container query cannot read the width token, so the component also sets data-narrow.
7351
+ */
7352
+
7353
+ .CollectionToolbar {
7354
+ container-type: inline-size;
7355
+ display: flex;
7356
+ flex-direction: column;
7357
+ gap: var(--sl-collection-toolbar-gap);
7358
+ margin-block-end: var(--sl-collection-toolbar-gap);
7359
+ }
7360
+
7361
+ .CollectionToolbarMain,
7362
+ .CollectionToolbarTrailing,
7363
+ .CollectionSelectionBar,
7364
+ .CollectionSort {
7365
+ display: flex;
7366
+ flex-wrap: wrap;
7367
+ align-items: center;
7368
+ gap: var(--sl-collection-toolbar-gap);
7369
+ }
7370
+
7371
+ .CollectionSearch {
7372
+ display: flex;
7373
+ align-items: center;
7374
+ gap: var(--sl-collection-toolbar-gap);
7375
+ min-width: 0;
7376
+ }
7377
+
7378
+ .CollectionSearch .Input {
7379
+ min-width: 0;
7380
+ }
7381
+
7382
+ .CollectionToolbarActions {
7383
+ display: flex;
7384
+ flex-wrap: wrap;
7385
+ gap: var(--sl-collection-toolbar-gap);
7386
+ margin-inline-start: auto;
7387
+ }
7388
+
7389
+ /* The width token is measured in JS (data-narrow). A container query cannot read a custom property. */
7390
+ .CollectionToolbar[data-narrow] .CollectionSearch,
7391
+ .CollectionView[data-narrow] .CollectionSearch {
7392
+ flex-basis: 100%;
7393
+ }
7394
+
7395
+ .CollectionCount {
7396
+ font-family: var(--sl-font-body-condense-font-family);
7397
+ font-size: var(--sl-font-body-condense-font-size);
7398
+ font-weight: var(--sl-font-body-condense-font-weight);
7399
+ line-height: var(--sl-font-body-condense-line-height);
7400
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7401
+ }
7402
+
7403
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7404
+ /* DataTable additions on top of .Table.
7405
+ *
7406
+ * Sort buttons fill the header cell and inherit its hover, so old aria-sort markup keeps
7407
+ * the hover it already had. The open row uses table.row-current, distinct from a selected row.
7408
+ * Loading dims the rows in place. Nothing here changes a plain .Table.
7409
+ */
7410
+
7411
+ .CollectionScroll {
7412
+ overflow: auto;
7413
+ max-width: 100%;
7414
+ }
7415
+
7416
+ .DataTable[data-size='sm'] {
7417
+ --sl-table-row-height: var(--sl-collection-row-height-sm);
7418
+ --sl-table-header-height: var(--sl-collection-header-height-sm);
7419
+ }
7420
+
7421
+ .DataTable[data-size='md'] {
7422
+ --sl-table-row-height: var(--sl-collection-row-height-md);
7423
+ --sl-table-header-height: var(--sl-collection-header-height-md);
7424
+ }
7425
+
7426
+ .Table th[aria-sort] > .TableSortButton {
7427
+ display: inline-flex;
7428
+ align-items: center;
7429
+ justify-content: inherit;
7430
+ gap: var(--sl-collection-toolbar-gap);
7431
+ width: 100%;
7432
+ height: 100%;
7433
+ margin: 0;
7434
+ padding: 0;
7435
+ border: 0;
7436
+ background: transparent;
7437
+ color: inherit;
7438
+ font: inherit;
7439
+ text-align: inherit;
7440
+ cursor: pointer;
7441
+ }
7442
+
7443
+ .TableSortIcon[data-state='none'] {
7444
+ visibility: hidden;
7445
+ }
7446
+
7447
+ .Table th[aria-sort]:hover .TableSortIcon[data-state='none'],
7448
+ .Table th[aria-sort]:focus-within .TableSortIcon[data-state='none'] {
7449
+ visibility: visible;
7450
+ }
7451
+
7452
+ .Table[data-sticky-row-header] tbody tr {
7453
+ --sl-row-fill: var(--sl-table-background);
7454
+ }
7455
+
7456
+ .Table[data-sticky-row-header] tbody tr:hover {
7457
+ --sl-row-fill: var(--sl-table-row-hover);
7458
+ }
7459
+
7460
+ .Table[data-sticky-row-header] tbody tr:is([aria-selected='true'], [data-selected]) {
7461
+ --sl-row-fill: var(--sl-table-row-selected);
7462
+ }
7463
+
7464
+ .Table[data-sticky-row-header] tbody tr[aria-current='true'] {
7465
+ --sl-row-fill: var(--sl-table-row-current);
7466
+ }
7467
+
7468
+ .Table[data-sticky-row-header] tbody th[scope='row'] {
7469
+ position: sticky;
7470
+ inset-inline-start: 0;
7471
+ z-index: var(--sl-z-index-docked);
7472
+ background: var(--sl-row-fill);
7473
+ }
7474
+
7475
+ .TableSortButton:focus-visible,
7476
+ .CollectionGroupButton:focus-visible,
7477
+ .CollectionRowButton:focus-visible {
7478
+ outline: var(--sl-focus-outline);
7479
+ outline-offset: var(--sl-focus-outline-offset);
7480
+ box-shadow: 0 0 0 var(--sl-focus-halo-spread) var(--sl-focus-halo-color);
7481
+ }
7482
+
7483
+ .Table tr[data-group] th {
7484
+ background: var(--sl-table-group-header-background);
7485
+ color: var(--sl-table-header-color);
7486
+ }
7487
+
7488
+ .CollectionGroupButton,
7489
+ .CollectionRowButton {
7490
+ margin: 0;
7491
+ padding: 0;
7492
+ border: 0;
7493
+ background: transparent;
7494
+ color: inherit;
7495
+ font: inherit;
7496
+ text-align: inherit;
7497
+ cursor: pointer;
7498
+ }
7499
+
7500
+ .DataTable[data-loading] tbody {
7501
+ opacity: var(--sl-item-opacity-disabled);
7502
+ transition: opacity var(--sl-duration-fast) var(--sl-easing-default);
7503
+ }
7504
+
7505
+ .CollectionSelectColumn {
7506
+ width: var(--sl-collection-selection-column-width);
7507
+ }
7508
+
7509
+ .Table th[data-width='min'],
7510
+ .Table td[data-width='min'] {
7511
+ width: min-content;
7512
+ white-space: nowrap;
7513
+ }
7514
+
7515
+ .CollectionStatus {
7516
+ font-family: var(--sl-font-body-condense-font-family);
7517
+ font-size: var(--sl-font-body-condense-font-size);
7518
+ font-weight: var(--sl-font-body-condense-font-weight);
7519
+ line-height: var(--sl-font-body-condense-line-height);
7520
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7521
+ color: var(--sl-table-subtle-color);
7522
+ }
7523
+
7524
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7525
+ /* DataList
7526
+ *
7527
+ * The same rows as the table, in one container with the table's borders, hover, selected
7528
+ * and current states. Not a stack of floating cards: the two views should read as one family.
7529
+ * variant=cards adds the surface radius and a gap when a queue should read as separate items.
7530
+ */
7531
+
7532
+ .DataList {
7533
+ font-family: var(--sl-font-body-condense-font-family);
7534
+ font-size: var(--sl-font-body-condense-font-size);
7535
+ font-weight: var(--sl-font-body-condense-font-weight);
7536
+ line-height: var(--sl-font-body-condense-line-height);
7537
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7538
+ color: var(--sl-table-color);
7539
+ }
7540
+
7541
+ .DataList ul {
7542
+ margin: 0;
7543
+ padding: 0;
7544
+ list-style: none;
7545
+ background: var(--sl-table-background);
7546
+ border: var(--sl-stroke-default) solid var(--sl-table-border-color);
7547
+ border-radius: var(--sl-table-radius);
7548
+ }
7549
+
7550
+ .DataList li {
7551
+ display: flex;
7552
+ align-items: flex-start;
7553
+ gap: var(--sl-collection-list-row-gap);
7554
+ padding-block: var(--sl-collection-list-row-padding-block);
7555
+ padding-inline: var(--sl-table-cell-padding-inline);
7556
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
7557
+ }
7558
+
7559
+ .DataList li:last-child {
7560
+ border-bottom: none;
7561
+ }
7562
+
7563
+ .DataList[data-size='md'] li {
7564
+ padding-block: var(--sl-collection-list-row-padding-block);
7565
+ min-height: var(--sl-collection-row-height-md);
7566
+ }
7567
+
7568
+ .DataList li[data-selected] {
7569
+ background: var(--sl-table-row-selected);
7570
+ color: var(--sl-table-color);
7571
+ }
7572
+
7573
+ .DataList li[aria-current='true'] {
7574
+ background: var(--sl-table-row-current);
7575
+ color: var(--sl-table-color);
7576
+ box-shadow: inset var(--sl-stroke-strong) 0 0 0 var(--sl-border-accent);
7577
+ }
7578
+
7579
+ @media (hover: hover) {
7580
+ .DataList li:hover:not([data-selected], [aria-current='true']) {
7581
+ background: var(--sl-table-row-hover);
7582
+ color: var(--sl-table-color);
7583
+ }
7584
+ }
7585
+
7586
+ .DataListPrimary {
7587
+ font-family: var(--sl-font-subtitle-condense-font-family);
7588
+ font-size: var(--sl-font-subtitle-condense-font-size);
7589
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
7590
+ line-height: var(--sl-font-subtitle-condense-line-height);
7591
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
7592
+ }
7593
+
7594
+ .DataListSecondary,
7595
+ .DataListMeta,
7596
+ .DataListSummary {
7597
+ font-family: var(--sl-font-body-condense-font-family);
7598
+ font-size: var(--sl-font-body-condense-font-size);
7599
+ font-weight: var(--sl-font-body-condense-font-weight);
7600
+ line-height: var(--sl-font-body-condense-line-height);
7601
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7602
+ color: var(--sl-table-subtle-color);
7603
+ }
7604
+
7605
+ .DataListBody {
7606
+ display: flex;
7607
+ flex: 1;
7608
+ flex-direction: column;
7609
+ gap: var(--sl-space-1);
7610
+ min-width: 0;
7611
+ }
7612
+
7613
+ .DataListMeta {
7614
+ display: flex;
7615
+ flex-wrap: wrap;
7616
+ gap: var(--sl-collection-list-row-gap);
7617
+ }
7618
+
7619
+ .DataListAmount {
7620
+ margin-inline-start: auto;
7621
+ font-variant-numeric: tabular-nums;
7622
+ }
7623
+
7624
+ .DataListGroup {
7625
+ background: var(--sl-table-group-header-background);
7626
+ color: var(--sl-table-header-color);
7627
+ }
7628
+
7629
+ .DataList[data-variant='cards'] ul {
7630
+ display: flex;
7631
+ flex-direction: column;
7632
+ gap: var(--sl-collection-list-row-gap);
7633
+ background: transparent;
7634
+ border: 0;
7635
+ }
7636
+
7637
+ .DataList[data-variant='cards'] li {
7638
+ background: var(--sl-table-background);
7639
+ border: var(--sl-stroke-default) solid var(--sl-table-border-color);
7640
+ border-radius: var(--sl-table-radius);
7641
+ }
7642
+
7643
+ .DataList[data-loading] ul {
7644
+ opacity: var(--sl-item-opacity-disabled);
7645
+ transition: opacity var(--sl-duration-fast) var(--sl-easing-default);
7646
+ }
7647
+
7648
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7649
+ /* Pagination
7650
+ *
7651
+ * Not tied to a collection. Anything with a page, a page count and a total can use it.
7652
+ * Previous and Next are quiet buttons. The count reads "1–25 of 312".
7653
+ */
7654
+
7655
+ .CollectionPagination {
7656
+ display: flex;
7657
+ flex-wrap: wrap;
7658
+ align-items: center;
7659
+ gap: var(--sl-collection-toolbar-gap);
7660
+ margin-block-start: var(--sl-collection-toolbar-gap);
7661
+ color: var(--sl-table-subtle-color);
7662
+ }
7663
+
7664
+ .CollectionPagination p {
7665
+ font-family: var(--sl-font-body-condense-font-family);
7666
+ font-size: var(--sl-font-body-condense-font-size);
7667
+ font-weight: var(--sl-font-body-condense-font-weight);
7668
+ line-height: var(--sl-font-body-condense-line-height);
7669
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7670
+ margin: 0;
7671
+ }
7672
+
7673
+ /* @scattered-light/loomiere-base-ui 0.7.0 · styles for @base-ui/react 1.9.0 */
7674
+ /* EditableList
7675
+ *
7676
+ * One table at every width, so a field is not submitted twice. Under the stack width each
7677
+ * field shows its own label, so the lost header association does not matter: the input's
7678
+ * name comes from that label, not from the column header.
7679
+ *
7680
+ * Move up / Move down would be quiet buttons in the last cell, ahead of any future drag handle.
7681
+ */
7682
+
7683
+ .EditableList {
7684
+ container-type: inline-size;
7685
+ }
7686
+
7687
+ .EditableListAdd,
7688
+ .EditableListError,
7689
+ .EditableListBalance {
7690
+ margin-block-start: var(--sl-collection-toolbar-gap);
7691
+ }
7692
+
7693
+ .EditableListFieldLabel {
7694
+ display: none;
7695
+ }
7696
+
7697
+ .EditableListBalance {
7698
+ font-family: var(--sl-font-body-condense-font-family);
7699
+ font-size: var(--sl-font-body-condense-font-size);
7700
+ font-weight: var(--sl-font-body-condense-font-weight);
7701
+ line-height: var(--sl-font-body-condense-line-height);
7702
+ letter-spacing: var(--sl-font-body-condense-letter-spacing);
7703
+ padding: var(--sl-space-2) var(--sl-space-3);
7704
+ border-radius: var(--sl-radius-control);
7705
+ }
7706
+
7707
+ .EditableListBalance[data-color] {
7708
+ background: var(--sl-scope-soft);
7709
+ color: var(--sl-scope-on-soft);
7710
+ }
7711
+
7712
+ .EditableListStackedTitle {
7713
+ display: none;
7714
+ font-family: var(--sl-font-subtitle-condense-font-family);
7715
+ font-size: var(--sl-font-subtitle-condense-font-size);
7716
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
7717
+ line-height: var(--sl-font-subtitle-condense-line-height);
7718
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
7719
+ }
7720
+
7721
+ .EditableList[data-stacked] .EditableListStackedTitle {
7722
+ display: block;
7723
+ }
7724
+
7725
+ .EditableListRowLead {
7726
+ width: 0;
7727
+ padding: 0;
7728
+ border: 0;
7729
+ }
7730
+
7731
+ .EditableList td .Input,
7732
+ .EditableList td input,
7733
+ .EditableList td select {
7734
+ width: 100%;
7735
+ }
7736
+
7737
+ /* The width token is measured in JS. data-stacked is that measurement. */
7738
+ .EditableList[data-stacked] {
7739
+ .EditableListTable,
7740
+ .EditableListTable thead,
7741
+ .EditableListTable tbody,
7742
+ .EditableListTable tr,
7743
+ .EditableListTable td {
7744
+ display: block;
7745
+ width: 100%;
7746
+ height: auto;
7747
+ }
7748
+
7749
+ .EditableListTable thead {
7750
+ position: absolute;
7751
+ width: var(--sl-space-px);
7752
+ height: var(--sl-space-px);
7753
+ overflow: hidden;
7754
+ clip: rect(0, 0, 0, 0);
7755
+ }
7756
+
7757
+ .EditableListTable tr {
7758
+ padding-block: var(--sl-collection-list-row-padding-block);
7759
+ border-bottom: var(--sl-stroke-default) solid var(--sl-table-row-border-color);
7760
+ }
7761
+
7762
+ .EditableListFieldLabel {
7763
+ display: block;
7764
+ font-family: var(--sl-font-subtitle-condense-font-family);
7765
+ font-size: var(--sl-font-subtitle-condense-font-size);
7766
+ font-weight: var(--sl-font-subtitle-condense-font-weight);
7767
+ line-height: var(--sl-font-subtitle-condense-line-height);
7768
+ letter-spacing: var(--sl-font-subtitle-condense-letter-spacing);
7769
+ }
7770
+ }