@moldable-ai/ui 0.2.26 → 0.2.31

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 (186) hide show
  1. package/dist/catalog/component-catalog.d.ts +9 -2
  2. package/dist/catalog/component-catalog.d.ts.map +1 -1
  3. package/dist/catalog/component-catalog.js +11 -7
  4. package/dist/catalog/core-control-stories.d.ts.map +1 -1
  5. package/dist/catalog/core-control-stories.js +1 -1
  6. package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
  7. package/dist/catalog/core-foundation-stories.js +15 -3
  8. package/dist/components/ui/app-frame.d.ts +20 -1
  9. package/dist/components/ui/app-frame.d.ts.map +1 -1
  10. package/dist/components/ui/app-frame.js +37 -7
  11. package/dist/components/ui/badge.d.ts +1 -1
  12. package/dist/components/ui/badge.js +1 -1
  13. package/dist/components/ui/button.d.ts +5 -3
  14. package/dist/components/ui/button.d.ts.map +1 -1
  15. package/dist/components/ui/button.js +39 -10
  16. package/dist/components/ui/card.d.ts +12 -2
  17. package/dist/components/ui/card.d.ts.map +1 -1
  18. package/dist/components/ui/card.js +3 -2
  19. package/dist/components/ui/checkbox.d.ts +4 -1
  20. package/dist/components/ui/checkbox.d.ts.map +1 -1
  21. package/dist/components/ui/checkbox.js +4 -4
  22. package/dist/components/ui/context-menu.js +6 -6
  23. package/dist/components/ui/date-field.d.ts +1 -1
  24. package/dist/components/ui/dropdown-menu.js +6 -6
  25. package/dist/components/ui/icon-button.d.ts +1 -1
  26. package/dist/components/ui/icon-button.d.ts.map +1 -1
  27. package/dist/components/ui/icon-button.js +1 -0
  28. package/dist/components/ui/index.d.ts +1 -0
  29. package/dist/components/ui/index.d.ts.map +1 -1
  30. package/dist/components/ui/index.js +1 -0
  31. package/dist/components/ui/input-group.d.ts +2 -2
  32. package/dist/components/ui/input.d.ts +6 -2
  33. package/dist/components/ui/input.d.ts.map +1 -1
  34. package/dist/components/ui/input.js +2 -2
  35. package/dist/components/ui/material.d.ts +8 -3
  36. package/dist/components/ui/material.d.ts.map +1 -1
  37. package/dist/components/ui/material.js +2 -2
  38. package/dist/components/ui/search-field.d.ts +3 -1
  39. package/dist/components/ui/search-field.d.ts.map +1 -1
  40. package/dist/components/ui/search-field.js +16 -6
  41. package/dist/components/ui/segmented-control.d.ts +3 -1
  42. package/dist/components/ui/segmented-control.d.ts.map +1 -1
  43. package/dist/components/ui/segmented-control.js +23 -17
  44. package/dist/components/ui/select.js +2 -2
  45. package/dist/components/ui/sidebar.d.ts +5 -3
  46. package/dist/components/ui/sidebar.d.ts.map +1 -1
  47. package/dist/components/ui/sidebar.js +53 -15
  48. package/dist/components/ui/status.d.ts +1 -1
  49. package/dist/components/ui/status.js +1 -1
  50. package/dist/components/ui/switch.d.ts +3 -1
  51. package/dist/components/ui/switch.d.ts.map +1 -1
  52. package/dist/components/ui/switch.js +3 -2
  53. package/dist/components/ui/toolbar-controls.d.ts +49 -0
  54. package/dist/components/ui/toolbar-controls.d.ts.map +1 -0
  55. package/dist/components/ui/toolbar-controls.js +47 -0
  56. package/dist/components/ui/toolbar.d.ts +5 -4
  57. package/dist/components/ui/toolbar.d.ts.map +1 -1
  58. package/dist/components/ui/toolbar.js +3 -3
  59. package/dist/index.d.ts +2 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +3 -1
  62. package/dist/lib/frame-lifecycle.d.ts +1 -0
  63. package/dist/lib/frame-lifecycle.d.ts.map +1 -1
  64. package/dist/lib/frame-lifecycle.js +7 -0
  65. package/dist/lib/theme.d.ts +39 -5
  66. package/dist/lib/theme.d.ts.map +1 -1
  67. package/dist/lib/theme.js +105 -17
  68. package/dist/tokens/contracts.d.ts +79 -0
  69. package/dist/tokens/contracts.d.ts.map +1 -0
  70. package/dist/tokens/contracts.js +57 -0
  71. package/dist/tokens/index.d.ts +2 -0
  72. package/dist/tokens/index.d.ts.map +1 -0
  73. package/dist/tokens/index.js +1 -0
  74. package/docs/README.md +2 -0
  75. package/docs/adaptive-materials.md +14 -9
  76. package/docs/design-tokens.md +10 -6
  77. package/docs/foundations.md +3 -3
  78. package/docs/macos-design-audit.md +144 -0
  79. package/docs/native-integration.md +4 -4
  80. package/docs/platform-architecture.md +189 -0
  81. package/docs/standalone-app-windows.md +37 -0
  82. package/docs/visual-regression.md +6 -8
  83. package/package.json +13 -1
  84. package/src/components/ui/accordion.md +46 -0
  85. package/src/components/ui/alert.md +12 -4
  86. package/src/components/ui/app-frame.md +8 -5
  87. package/src/components/ui/aspect-ratio.md +37 -0
  88. package/src/components/ui/avatar.md +48 -0
  89. package/src/components/ui/breadcrumb.md +52 -0
  90. package/src/components/ui/button-group.md +43 -0
  91. package/src/components/ui/button.md +20 -4
  92. package/src/components/ui/calendar.md +42 -0
  93. package/src/components/ui/card.md +43 -0
  94. package/src/components/ui/carousel.md +47 -0
  95. package/src/components/ui/chart.md +52 -0
  96. package/src/components/ui/checkbox.md +36 -0
  97. package/src/components/ui/collapsible.md +2 -3
  98. package/src/components/ui/color-well.md +14 -4
  99. package/src/components/ui/combobox.md +3 -3
  100. package/src/components/ui/confirm-dialog.md +5 -4
  101. package/src/components/ui/context-menu.md +3 -2
  102. package/src/components/ui/date-field.md +6 -1
  103. package/src/components/ui/date-picker.md +6 -3
  104. package/src/components/ui/dialog.md +14 -12
  105. package/src/components/ui/drawer.md +58 -0
  106. package/src/components/ui/error-boundary-view.md +1 -1
  107. package/src/components/ui/field.md +2 -1
  108. package/src/components/ui/form.md +71 -0
  109. package/src/components/ui/grid.md +4 -3
  110. package/src/components/ui/icon-button.md +4 -1
  111. package/src/components/ui/input-group.md +49 -0
  112. package/src/components/ui/input-otp.md +56 -0
  113. package/src/components/ui/input.md +40 -0
  114. package/src/components/ui/inspector.md +47 -7
  115. package/src/components/ui/item.md +5 -3
  116. package/src/components/ui/kbd.md +30 -0
  117. package/src/components/ui/label.md +29 -0
  118. package/src/components/ui/list.md +2 -2
  119. package/src/components/ui/material.md +25 -12
  120. package/src/components/ui/menu-items.md +60 -0
  121. package/src/components/ui/menubar.md +58 -0
  122. package/src/components/ui/message-scroller-primitive.md +70 -0
  123. package/src/components/ui/message-scroller.md +86 -0
  124. package/src/components/ui/navigation-button-group.md +4 -3
  125. package/src/components/ui/navigation-menu.md +52 -0
  126. package/src/components/ui/number-input.md +8 -0
  127. package/src/components/ui/pagination.md +51 -0
  128. package/src/components/ui/panel.md +6 -0
  129. package/src/components/ui/popover.md +10 -7
  130. package/src/components/ui/progress.md +31 -0
  131. package/src/components/ui/radio-group.md +36 -0
  132. package/src/components/ui/resizable.md +2 -1
  133. package/src/components/ui/scroll-area.md +3 -1
  134. package/src/components/ui/search-field.md +6 -1
  135. package/src/components/ui/segmented-control.md +6 -1
  136. package/src/components/ui/separator.md +35 -0
  137. package/src/components/ui/sidebar.md +20 -3
  138. package/src/components/ui/skeleton.md +36 -0
  139. package/src/components/ui/slider.md +58 -0
  140. package/src/components/ui/spinner.md +41 -0
  141. package/src/components/ui/split-view.md +8 -4
  142. package/src/components/ui/switch.md +44 -0
  143. package/src/components/ui/table.md +7 -7
  144. package/src/components/ui/tabs.md +3 -1
  145. package/src/components/ui/textarea.md +41 -0
  146. package/src/components/ui/toggle-group.md +2 -2
  147. package/src/components/ui/toggle.md +9 -9
  148. package/src/components/ui/toolbar-controls.md +83 -0
  149. package/src/components/ui/toolbar.md +12 -6
  150. package/src/styles/index.css +199 -107
  151. package/src/tokens/contracts.ts +131 -0
  152. package/src/tokens/index.css +6 -0
  153. package/src/tokens/index.ts +23 -0
  154. package/src/tokens/macos-26/README.md +37 -0
  155. package/src/tokens/macos-26/aliases.css +53 -0
  156. package/src/tokens/macos-26/compatibility.css +7 -0
  157. package/src/tokens/macos-26/index.css +3 -0
  158. package/src/tokens/macos-26/source/provenance.generated.json +28 -0
  159. package/src/tokens/macos-26/source/sidebar.generated.css +29 -0
  160. package/src/tokens/macos-26/source.css +7 -0
  161. package/src/tokens/macos-26/web-adaptations.json +25 -0
  162. package/src/tokens/macos-26/web-adaptations.md +15 -0
  163. package/src/tokens/macos-27/accessibility.css +11 -0
  164. package/src/tokens/macos-27/aliases.css +304 -0
  165. package/src/tokens/macos-27/compatibility.css +212 -0
  166. package/src/tokens/macos-27/index.css +15 -0
  167. package/src/tokens/macos-27/recipes.css +23 -0
  168. package/src/tokens/macos-27/source/chrome.generated.css +338 -0
  169. package/src/tokens/macos-27/source/colors.generated.css +140 -0
  170. package/src/tokens/macos-27/source/context.generated.css +18 -0
  171. package/src/tokens/macos-27/source/controls.generated.css +764 -0
  172. package/src/tokens/macos-27/source/effects.generated.css +68 -0
  173. package/src/tokens/macos-27/source/kit.generated.css +50 -0
  174. package/src/tokens/macos-27/source/overlays-status.generated.css +931 -0
  175. package/src/tokens/macos-27/source/paint-styles.generated.css +81 -0
  176. package/src/tokens/macos-27/source/provenance.generated.json +62 -0
  177. package/src/tokens/macos-27/source/sizes.generated.css +385 -0
  178. package/src/tokens/macos-27/source/source.generated.json +554 -0
  179. package/src/tokens/macos-27/source/text-styles.generated.css +116 -0
  180. package/src/tokens/macos-27/source.css +17 -0
  181. package/src/tokens/macos-27/web-adaptations.css +98 -0
  182. package/src/tokens/macos-27/web-adaptations.json +163 -0
  183. package/src/tokens/macos-27/web-adaptations.md +117 -0
  184. package/src/tokens/moldable/brand.css +48 -0
  185. package/src/tokens/moldable/index.css +1 -0
  186. package/src/tokens/platform-contract.test.ts +290 -0
@@ -12,9 +12,9 @@ embedded view.
12
12
  <ToolbarDescription>Local workspace</ToolbarDescription>
13
13
  </ToolbarContent>
14
14
  <ToolbarActions>
15
- <Button size="icon-sm" aria-label="New note">
15
+ <ToolbarIconButton label="New note" tooltip>
16
16
  <Plus />
17
- </Button>
17
+ </ToolbarIconButton>
18
18
  </ToolbarActions>
19
19
  </Toolbar>
20
20
  ```
@@ -28,12 +28,18 @@ when there is no useful view context; the remaining toolbar still provides a
28
28
  drag surface and a safe home for right-aligned actions.
29
29
 
30
30
  The `inset` prop defaults to `auto`. Use `none` for a top toolbar that is not
31
- window chrome, `windowControls` to force the standard control lane, or
32
- `windowControlsAndButton` when another leading control sits beside the native
33
- traffic lights. Set `draggable={false}` only for top toolbars that are nested
34
- inside app content.
31
+ window chrome, `windowControls` to explicitly declare the standard control
32
+ lane, or `windowControlsAndButton` when another leading control sits beside
33
+ the native traffic lights. Set `draggable={false}` only for top toolbars that
34
+ are nested inside app content.
35
35
 
36
36
  The default toolbar uses `material="regular"`. The `plain` and `panel` variants
37
37
  default to `material="none"`; pass a material explicitly only when the toolbar
38
38
  actually floats over content. Reserve `material="clear"` for compact controls
39
39
  over media or a richly colored canvas.
40
+
41
+ Use the precomposed controls in
42
+ [`toolbar-controls.md`](./toolbar-controls.md) for native-sized Back, Sidebar,
43
+ Overflow, grouped-action, and editable-title behavior. Keep only closely
44
+ related actions in a shared group; a single capsule containing every command
45
+ does not communicate command hierarchy.
@@ -1,5 +1,6 @@
1
1
  @import 'tailwindcss';
2
2
  @import 'tw-animate-css';
3
+ @import '../tokens/index.css';
3
4
 
4
5
  @plugin "@tailwindcss/typography";
5
6
 
@@ -186,11 +187,17 @@
186
187
  --font-sans: var(--font-family-ui);
187
188
  --font-mono: var(--font-family-mono);
188
189
 
190
+ --text-10: 10px;
189
191
  --text-11: 11px;
192
+ --text-12: 12px;
190
193
  --text-13: 13px;
194
+ --text-15: 15px;
191
195
  --text-16: 16px;
196
+ --text-17: 17px;
192
197
  --text-18: 18px;
198
+ --text-22: 22px;
193
199
  --text-24: 24px;
200
+ --text-26: 26px;
194
201
  --text-ui-display: var(--type-display-size);
195
202
  --text-ui-display--line-height: var(--type-display-line-height);
196
203
  --text-ui-display--font-weight: var(--type-display-weight);
@@ -232,6 +239,7 @@
232
239
  --spacing-control-sm: var(--density-control-height-sm);
233
240
  --spacing-control-md: var(--density-control-height-md);
234
241
  --spacing-control-lg: var(--density-control-height-lg);
242
+ --spacing-control-xl: var(--density-control-height-xl);
235
243
  --spacing-row: var(--density-row-height);
236
244
  --spacing-toolbar: var(--density-toolbar-height);
237
245
  --spacing-pane: var(--density-pane-padding);
@@ -241,6 +249,7 @@
241
249
  --ease-enter: var(--motion-ease-enter);
242
250
  --ease-exit: var(--motion-ease-exit);
243
251
  --ease-spring: var(--motion-ease-spring);
252
+ --shadow-card: var(--material-shadow-card);
244
253
  --shadow-panel: var(--material-shadow-panel);
245
254
  --shadow-overlay: var(--material-shadow-overlay);
246
255
  --shadow-dialog: var(--material-shadow-dialog);
@@ -268,6 +277,10 @@
268
277
  --color-control-disabled: var(--control-disabled);
269
278
  --color-control-focus: var(--control-focus);
270
279
  --color-control-invalid: var(--control-invalid);
280
+ --color-toolbar-control: var(--toolbar-control-background);
281
+ --color-toolbar-control-hover: var(--toolbar-control-hover);
282
+ --color-toolbar-control-pressed: var(--toolbar-control-pressed);
283
+ --color-toolbar-control-border: var(--toolbar-control-border);
271
284
  --color-window-chrome: var(--window-chrome-background);
272
285
  --color-window-chrome-foreground: var(--window-chrome-foreground);
273
286
  --color-window-chrome-muted: var(--window-chrome-muted-foreground);
@@ -278,6 +291,8 @@
278
291
  --color-popover-foreground: var(--popover-foreground);
279
292
  --color-primary: var(--primary);
280
293
  --color-primary-foreground: var(--primary-foreground);
294
+ --color-prominent: var(--prominent);
295
+ --color-prominent-foreground: var(--prominent-foreground);
281
296
  --color-secondary: var(--secondary);
282
297
  --color-secondary-foreground: var(--secondary-foreground);
283
298
  --color-muted: var(--muted);
@@ -718,38 +733,43 @@
718
733
  system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
719
734
  --font-family-mono: ui-monospace, Menlo, Consolas, monospace;
720
735
 
721
- --type-display-size: var(--text-24);
722
- --type-display-line-height: 28px;
723
- --type-display-weight: 600;
724
- --type-display-tracking: -0.02em;
725
- --type-heading-size: var(--text-18);
736
+ --type-display-size: var(--text-26);
737
+ --type-display-line-height: 32px;
738
+ --type-display-weight: 700;
739
+ --type-display-tracking: 0;
740
+ --type-heading-size: var(--text-17);
726
741
  --type-heading-line-height: 22px;
727
- --type-heading-weight: 600;
728
- --type-heading-tracking: -0.012em;
729
- --type-title-size: var(--text-16);
742
+ --type-heading-weight: 700;
743
+ --type-heading-tracking: 0;
744
+ --type-title-size: var(--text-15);
730
745
  --type-title-line-height: 20px;
731
746
  --type-title-weight: 600;
732
- --type-title-tracking: -0.006em;
747
+ --type-title-tracking: 0;
733
748
  --type-body-size: var(--text-13);
734
- --type-body-line-height: 18px;
749
+ --type-body-line-height: 16px;
735
750
  --type-label-size: var(--text-13);
736
751
  --type-label-line-height: 16px;
737
752
  --type-caption-size: var(--text-11);
738
753
  --type-caption-line-height: 14px;
739
-
740
- --density-control-height-xs: 1.5rem;
741
- --density-control-height-sm: 1.75rem;
742
- --density-control-height-md: 2rem;
743
- --density-control-height-lg: 2.25rem;
744
- --density-control-gap: 0.3125rem;
754
+ --type-badge-size: var(--text-11);
755
+ --type-badge-line-height: 14px;
756
+
757
+ --density-control-height-xs: 1rem;
758
+ --density-control-height-sm: 1.25rem;
759
+ --density-control-height-md: 1.5rem;
760
+ --density-control-height-lg: 1.75rem;
761
+ --density-control-height-xl: 2.25rem;
762
+ --density-control-gap: 0.25rem;
745
763
  --density-control-padding-inline: 0.625rem;
764
+ --density-badge-height: 1.125rem;
765
+ --density-badge-padding-inline: 0.375rem;
746
766
  --density-row-height: 2rem;
747
767
  --density-toolbar-height: 2.375rem;
748
768
  --density-pane-padding: 0.625rem;
749
769
  --density-section-gap: 0.875rem;
750
770
 
751
- --shape-control: 10px;
752
- --shape-checkbox: 4px;
771
+ --shape-control: 6px;
772
+ --shape-checkbox: 5px;
753
773
  --shape-popover: 12px;
754
774
  --shape-card: 12px;
755
775
  --shape-group: 12px;
@@ -769,24 +789,26 @@
769
789
  --motion-ease-spring: cubic-bezier(0.22, 1.15, 0.36, 1);
770
790
 
771
791
  --radius: var(--shape-card);
772
- --background: oklch(1 0 0);
773
- --foreground: oklch(0.141 0.005 285.823);
774
- --card: oklch(1 0 0);
775
- --card-foreground: oklch(0.141 0.005 285.823);
776
- --popover: oklch(1 0 0);
777
- --popover-foreground: oklch(0.141 0.005 285.823);
792
+ --background: #fff;
793
+ --foreground: rgb(0 0 0 / 85%);
794
+ --card: #fff;
795
+ --card-foreground: rgb(0 0 0 / 85%);
796
+ --popover: #fff;
797
+ --popover-foreground: rgb(0 0 0 / 85%);
778
798
  --primary: oklch(0.205 0 0);
779
799
  --primary-foreground: oklch(0.985 0 0);
780
- --secondary: oklch(0.967 0.001 286.375);
781
- --secondary-foreground: oklch(0.21 0.006 285.885);
782
- --muted: oklch(0.967 0.001 286.375);
783
- --muted-foreground: oklch(0.5 0.016 285.938);
784
- --accent: oklch(0.967 0.001 286.375);
785
- --accent-foreground: oklch(0.21 0.006 285.885);
800
+ --prominent: #0088ff;
801
+ --prominent-foreground: #fff;
802
+ --secondary: rgb(0 0 0 / 8%);
803
+ --secondary-foreground: rgb(0 0 0 / 85%);
804
+ --muted: rgb(0 0 0 / 5%);
805
+ --muted-foreground: rgb(0 0 0 / 50%);
806
+ --accent: rgb(0 0 0 / 10%);
807
+ --accent-foreground: rgb(0 0 0 / 85%);
786
808
  --destructive: oklch(0.5866 0.1994 31.76);
787
809
  --destructive-foreground: oklch(0.985 0 0);
788
- --border: oklch(0.92 0.004 286.32);
789
- --input: oklch(0.92 0.004 286.32);
810
+ --border: rgb(0 0 0 / 10%);
811
+ --input: rgb(0 0 0 / 10%);
790
812
  --ring: oklch(0.2 0 0 / 48%);
791
813
  --model-effort-blue: #339cff;
792
814
  --model-effort-purple: #924ff7;
@@ -851,46 +873,60 @@
851
873
  );
852
874
  --control-focus: var(--ring);
853
875
  --control-invalid: var(--destructive);
854
-
855
- --material-blur-toolbar: 16px;
856
- --material-blur-overlay: 20px;
857
- --material-saturation: 1.12;
858
- --material-regular-fill: color-mix(
876
+ --toolbar-control-background: rgb(255 255 255 / 42%);
877
+ --toolbar-control-hover: color-mix(
859
878
  in oklch,
860
- var(--background) 76%,
861
- transparent
879
+ var(--background) 84%,
880
+ var(--foreground) 8%
862
881
  );
863
- --material-regular-fallback: color-mix(
882
+ --toolbar-control-pressed: color-mix(
864
883
  in oklch,
865
- var(--background) 94%,
866
- var(--foreground) 6%
884
+ var(--background) 74%,
885
+ var(--foreground) 14%
867
886
  );
887
+ --toolbar-control-border: rgb(0 0 0 / 10%);
888
+ --toolbar-control-shadow:
889
+ inset 0 1px 0 color-mix(in oklch, white 42%, transparent),
890
+ 0 1px 2px oklch(0.15 0.005 285 / 8%);
891
+
892
+ --material-blur-toolbar: 6px;
893
+ --material-blur-overlay: 30px;
894
+ --material-saturation: 1;
895
+ --material-ultra-thick-fill: rgb(236 236 236 / 88%);
896
+ --material-thick-fill: rgb(246 246 246 / 72%);
897
+ --material-medium-fill: rgb(246 246 246 / 60%);
898
+ --material-thin-fill: rgb(246 246 246 / 48%);
899
+ --material-ultra-thin-fill: rgb(246 246 246 / 36%);
900
+ --material-ultra-thick-fallback: #ececec;
901
+ --material-thick-fallback: #f6f6f6;
902
+ --material-medium-fallback: #f6f6f6;
903
+ --material-thin-fallback: #f6f6f6;
904
+ --material-ultra-thin-fallback: #f6f6f6;
905
+ --material-standard-blur: 30px;
906
+ --material-regular-fill: var(--material-medium-fill);
907
+ --material-regular-fallback: var(--material-medium-fallback);
868
908
  --material-regular-border: color-mix(
869
909
  in oklch,
870
910
  var(--foreground) 10%,
871
911
  transparent
872
912
  );
873
913
  --material-regular-highlight: oklch(1 0 0 / 42%);
874
- --material-regular-blur: 20px;
875
- --material-regular-saturation: 1.18;
876
- --material-clear-fill: color-mix(
877
- in oklch,
878
- var(--background) 24%,
879
- transparent
880
- );
881
- --material-clear-fallback: color-mix(
882
- in oklch,
883
- var(--background) 88%,
884
- var(--foreground) 12%
885
- );
914
+ --material-regular-blur: var(--material-standard-blur);
915
+ --material-regular-saturation: 1;
916
+ --material-clear-fill: var(--material-ultra-thin-fill);
917
+ --material-clear-fallback: var(--material-ultra-thin-fallback);
886
918
  --material-clear-border: color-mix(
887
919
  in oklch,
888
920
  var(--foreground) 14%,
889
921
  transparent
890
922
  );
891
923
  --material-clear-highlight: oklch(1 0 0 / 28%);
892
- --material-clear-blur: 12px;
893
- --material-clear-saturation: 1.24;
924
+ --material-clear-blur: var(--material-standard-blur);
925
+ --material-clear-saturation: 1;
926
+ /* In-flow structure: never map this role to overlay or glass elevation. */
927
+ --material-shadow-card: 0 1px 2px oklch(0.15 0.005 285 / 6%);
928
+ --material-shadow-sidebar:
929
+ 0 1px 2px oklch(0.15 0.005 285 / 4%), 0 3px 10px oklch(0.15 0.005 285 / 4%);
894
930
  --material-shadow-panel:
895
931
  inset 0 0 0 1px var(--separator), 0 1px 2px oklch(0.15 0.005 285 / 5%),
896
932
  0 5px 14px oklch(0.15 0.005 285 / 5%);
@@ -952,9 +988,7 @@
952
988
  * toolbars retain their density-specific compact sizing.
953
989
  */
954
990
  :root[data-moldable-display-mode='window'][data-moldable-window-titlebar='app']
955
- [data-slot='toolbar'][data-position='top']:not(
956
- [data-window-inset='none']
957
- ) {
991
+ [data-slot='toolbar'][data-position='top']:not([data-window-inset='none']) {
958
992
  min-height: max(3.25rem, var(--window-titlebar-height, 0px));
959
993
  padding-inline-start: max(
960
994
  var(--density-control-padding-inline, 0.625rem),
@@ -975,10 +1009,11 @@
975
1009
  }
976
1010
 
977
1011
  :where([data-density='compact']) {
978
- --density-control-height-xs: 1.375rem;
979
- --density-control-height-sm: 1.75rem;
980
- --density-control-height-md: 2rem;
981
- --density-control-height-lg: 2.25rem;
1012
+ --density-control-height-xs: 1rem;
1013
+ --density-control-height-sm: 1.25rem;
1014
+ --density-control-height-md: 1.5rem;
1015
+ --density-control-height-lg: 1.75rem;
1016
+ --density-control-height-xl: 2.25rem;
982
1017
  --density-control-gap: 0.25rem;
983
1018
  --density-control-padding-inline: 0.625rem;
984
1019
  --density-row-height: 1.875rem;
@@ -992,6 +1027,7 @@
992
1027
  --density-control-height-sm: 2.25rem;
993
1028
  --density-control-height-md: 2.5rem;
994
1029
  --density-control-height-lg: 2.75rem;
1030
+ --density-control-height-xl: 3rem;
995
1031
  --density-control-gap: 0.5rem;
996
1032
  --density-control-padding-inline: 1rem;
997
1033
  --density-row-height: 2.75rem;
@@ -1001,20 +1037,22 @@
1001
1037
  }
1002
1038
 
1003
1039
  .dark {
1004
- --background: oklch(0.235 0 0);
1005
- --foreground: oklch(0.985 0 0);
1006
- --card: oklch(0.269 0.0018 286.28);
1007
- --card-foreground: oklch(0.985 0 0);
1008
- --popover: oklch(0.269 0.0018 286.28);
1009
- --popover-foreground: oklch(0.985 0 0);
1040
+ --background: #1d1f1f;
1041
+ --foreground: rgb(255 255 255 / 85%);
1042
+ --card: #242424;
1043
+ --card-foreground: rgb(255 255 255 / 85%);
1044
+ --popover: #242424;
1045
+ --popover-foreground: rgb(255 255 255 / 85%);
1010
1046
  --primary: oklch(0.985 0 0);
1011
1047
  --primary-foreground: oklch(0.205 0 0);
1012
- --secondary: oklch(0.3375 0.0035 286.21);
1013
- --secondary-foreground: oklch(0.985 0 0);
1014
- --muted: oklch(0.3375 0.0035 286.21);
1015
- --muted-foreground: oklch(0.74 0.012 286);
1016
- --accent: oklch(0.3375 0.0035 286.21);
1017
- --accent-foreground: oklch(0.985 0 0);
1048
+ --prominent: #0091ff;
1049
+ --prominent-foreground: #fff;
1050
+ --secondary: rgb(255 255 255 / 8%);
1051
+ --secondary-foreground: rgb(255 255 255 / 85%);
1052
+ --muted: rgb(255 255 255 / 5%);
1053
+ --muted-foreground: rgb(255 255 255 / 55%);
1054
+ --accent: rgb(255 255 255 / 10%);
1055
+ --accent-foreground: rgb(255 255 255 / 85%);
1018
1056
  --destructive: oklch(0.704 0.191 22.216);
1019
1057
  --destructive-foreground: oklch(0.985 0 0);
1020
1058
  --border: oklch(1 0 0 / 10%);
@@ -1028,13 +1066,13 @@
1028
1066
  --chart-3: var(--pending);
1029
1067
  --chart-4: var(--neutral);
1030
1068
  --chart-5: var(--accent-foreground);
1031
- --sidebar: oklch(0.235 0 0);
1069
+ --sidebar: #1b1d1e;
1032
1070
  --sidebar-foreground: oklch(0.985 0 0);
1033
1071
  --sidebar-primary: oklch(0.7145 0.185 45.03);
1034
1072
  --sidebar-primary-foreground: oklch(0.985 0 0);
1035
- --sidebar-accent: oklch(0.3375 0.0035 286.21);
1036
- --sidebar-accent-foreground: oklch(0.985 0 0);
1037
- --sidebar-border: oklch(1 0 0 / 10%);
1073
+ --sidebar-accent: color-mix(in srgb, #0091ff 14%, transparent);
1074
+ --sidebar-accent-foreground: #0091ff;
1075
+ --sidebar-border: #394043;
1038
1076
  --sidebar-ring: var(--ring);
1039
1077
  --info: oklch(0.72 0.15 250);
1040
1078
  --info-foreground: oklch(0.78 0.11 250);
@@ -1050,30 +1088,30 @@
1050
1088
  --status-stopped: var(--neutral);
1051
1089
  --status-pending: var(--pending);
1052
1090
  --status-error: var(--destructive);
1053
- --material-regular-fill: color-mix(
1054
- in oklch,
1055
- var(--background) 68%,
1056
- transparent
1057
- );
1058
- --material-regular-fallback: color-mix(
1059
- in oklch,
1060
- var(--background) 88%,
1061
- var(--foreground) 12%
1062
- );
1091
+ --toolbar-control-background: rgb(153 153 153 / 17%);
1092
+ --toolbar-control-border: rgb(255 255 255 / 10%);
1093
+ --material-ultra-thick-fill: rgb(0 0 0 / 50%);
1094
+ --material-thick-fill: rgb(0 0 0 / 40%);
1095
+ --material-medium-fill: rgb(0 0 0 / 29%);
1096
+ --material-thin-fill: rgb(0 0 0 / 20%);
1097
+ --material-ultra-thin-fill: rgb(0 0 0 / 10%);
1098
+ --material-ultra-thick-fallback: #000;
1099
+ --material-thick-fallback: #000;
1100
+ --material-medium-fallback: #000;
1101
+ --material-thin-fallback: #000;
1102
+ --material-ultra-thin-fallback: #000;
1103
+ --material-regular-fill: var(--material-medium-fill);
1104
+ --material-regular-fallback: var(--material-medium-fallback);
1063
1105
  --material-regular-border: oklch(1 0 0 / 14%);
1064
1106
  --material-regular-highlight: oklch(1 0 0 / 12%);
1065
- --material-clear-fill: color-mix(
1066
- in oklch,
1067
- var(--background) 20%,
1068
- transparent
1069
- );
1070
- --material-clear-fallback: color-mix(
1071
- in oklch,
1072
- var(--background) 78%,
1073
- var(--foreground) 22%
1074
- );
1107
+ --material-clear-fill: var(--material-ultra-thin-fill);
1108
+ --material-clear-fallback: var(--material-ultra-thin-fallback);
1075
1109
  --material-clear-border: oklch(1 0 0 / 18%);
1076
1110
  --material-clear-highlight: oklch(1 0 0 / 10%);
1111
+ /* In-flow structure: never map this role to overlay or glass elevation. */
1112
+ --material-shadow-card: 0 1px 2px oklch(0 0 0 / 24%);
1113
+ --material-shadow-sidebar:
1114
+ 0 1px 2px oklch(0 0 0 / 18%), 0 3px 10px oklch(0 0 0 / 12%);
1077
1115
  --material-shadow-panel:
1078
1116
  inset 0 0 0 1px var(--separator), 0 2px 5px oklch(0 0 0 / 28%),
1079
1117
  0 8px 22px oklch(0 0 0 / 22%);
@@ -1132,6 +1170,7 @@
1132
1170
  transparent
1133
1171
  );
1134
1172
  --material-clear-border: var(--separator-strong);
1173
+ --material-shadow-card: none;
1135
1174
  --material-shadow-panel: inset 0 0 0 1px var(--separator-strong);
1136
1175
  --material-shadow-overlay: inset 0 0 0 1px var(--separator-strong);
1137
1176
  --material-shadow-dialog: inset 0 0 0 1px var(--separator-strong);
@@ -1175,6 +1214,7 @@
1175
1214
  transparent
1176
1215
  );
1177
1216
  --material-clear-border: var(--separator-strong);
1217
+ --material-shadow-card: none;
1178
1218
  --material-shadow-panel: inset 0 0 0 1px var(--separator-strong);
1179
1219
  --material-shadow-overlay: inset 0 0 0 1px var(--separator-strong);
1180
1220
  --material-shadow-dialog: inset 0 0 0 1px var(--separator-strong);
@@ -1204,6 +1244,11 @@
1204
1244
  --control-disabled: transparent;
1205
1245
  --control-focus: Highlight;
1206
1246
  --control-invalid: Mark;
1247
+ --toolbar-control-background: Canvas;
1248
+ --toolbar-control-hover: Canvas;
1249
+ --toolbar-control-pressed: Canvas;
1250
+ --toolbar-control-border: ButtonBorder;
1251
+ --toolbar-control-shadow: none;
1207
1252
  --material-regular-fill: Canvas;
1208
1253
  --material-regular-fallback: Canvas;
1209
1254
  --material-regular-border: ButtonBorder;
@@ -1219,6 +1264,7 @@
1219
1264
  --material-blur-toolbar: 0px;
1220
1265
  --material-blur-overlay: 0px;
1221
1266
  --material-saturation: 1;
1267
+ --material-shadow-card: none;
1222
1268
  --material-shadow-panel: none;
1223
1269
  --material-shadow-overlay: none;
1224
1270
  --material-shadow-dialog: none;
@@ -1229,6 +1275,10 @@
1229
1275
  :where([data-transparency='reduced']) {
1230
1276
  --surface-toolbar: var(--background);
1231
1277
  --surface-overlay: var(--popover);
1278
+ --toolbar-control-background: var(--background);
1279
+ --toolbar-control-hover: var(--accent);
1280
+ --toolbar-control-pressed: var(--control-pressed);
1281
+ --toolbar-control-shadow: inset 0 0 0 1px var(--separator);
1232
1282
  --material-regular-fill: var(--material-regular-fallback);
1233
1283
  --material-regular-blur: 0px;
1234
1284
  --material-regular-saturation: 1;
@@ -1244,6 +1294,10 @@
1244
1294
  :root {
1245
1295
  --surface-toolbar: var(--background);
1246
1296
  --surface-overlay: var(--popover);
1297
+ --toolbar-control-background: var(--background);
1298
+ --toolbar-control-hover: var(--accent);
1299
+ --toolbar-control-pressed: var(--control-pressed);
1300
+ --toolbar-control-shadow: inset 0 0 0 1px var(--separator);
1247
1301
  --material-regular-fill: var(--material-regular-fallback);
1248
1302
  --material-regular-blur: 0px;
1249
1303
  --material-regular-saturation: 1;
@@ -1278,8 +1332,6 @@
1278
1332
  .moldable-material {
1279
1333
  --material-active-fill: var(--material-regular-fill);
1280
1334
  --material-active-fallback: var(--material-regular-fallback);
1281
- --material-active-border: var(--material-regular-border);
1282
- --material-active-highlight: var(--material-regular-highlight);
1283
1335
  --material-active-blur: var(--material-regular-blur);
1284
1336
  --material-active-saturation: var(--material-regular-saturation);
1285
1337
  --material-active-shadow: none;
@@ -1287,21 +1339,61 @@
1287
1339
  position: relative;
1288
1340
  isolation: isolate;
1289
1341
  background-color: var(--material-active-fallback);
1290
- border-color: var(--material-active-border);
1291
- box-shadow:
1292
- inset 0 1px 0 var(--material-active-highlight),
1293
- var(--material-active-shadow);
1342
+ box-shadow: var(--material-active-shadow);
1294
1343
  }
1295
1344
 
1296
1345
  .moldable-material[data-material='clear'] {
1297
1346
  --material-active-fill: var(--material-clear-fill);
1298
1347
  --material-active-fallback: var(--material-clear-fallback);
1299
- --material-active-border: var(--material-clear-border);
1300
- --material-active-highlight: var(--material-clear-highlight);
1301
1348
  --material-active-blur: var(--material-clear-blur);
1302
1349
  --material-active-saturation: var(--material-clear-saturation);
1303
1350
  }
1304
1351
 
1352
+ .moldable-material[data-material='ultra-thick'] {
1353
+ --material-active-fill: var(--material-ultra-thick-fill);
1354
+ --material-active-fallback: var(--material-ultra-thick-fallback);
1355
+ --material-active-blur: var(--material-standard-blur);
1356
+ --material-active-saturation: 1;
1357
+ }
1358
+
1359
+ .moldable-material[data-material='thick'] {
1360
+ --material-active-fill: var(--material-thick-fill);
1361
+ --material-active-fallback: var(--material-thick-fallback);
1362
+ --material-active-blur: var(--material-standard-blur);
1363
+ --material-active-saturation: 1;
1364
+ }
1365
+
1366
+ .moldable-material[data-material='medium'] {
1367
+ --material-active-fill: var(--material-medium-fill);
1368
+ --material-active-fallback: var(--material-medium-fallback);
1369
+ --material-active-blur: var(--material-standard-blur);
1370
+ --material-active-saturation: 1;
1371
+ }
1372
+
1373
+ .moldable-material[data-material='thin'] {
1374
+ --material-active-fill: var(--material-thin-fill);
1375
+ --material-active-fallback: var(--material-thin-fallback);
1376
+ --material-active-blur: var(--material-standard-blur);
1377
+ --material-active-saturation: 1;
1378
+ }
1379
+
1380
+ .moldable-material[data-material='ultra-thin'] {
1381
+ --material-active-fill: var(--material-ultra-thin-fill);
1382
+ --material-active-fallback: var(--material-ultra-thin-fallback);
1383
+ --material-active-blur: var(--material-standard-blur);
1384
+ --material-active-saturation: 1;
1385
+ }
1386
+
1387
+ :where(
1388
+ [data-slot='button'][data-variant='toolbar'],
1389
+ [data-slot='toolbar-control-group'][data-appearance='chrome']
1390
+ ) {
1391
+ -webkit-backdrop-filter: blur(var(--material-blur-toolbar))
1392
+ saturate(var(--material-saturation));
1393
+ backdrop-filter: blur(var(--material-blur-toolbar))
1394
+ saturate(var(--material-saturation));
1395
+ }
1396
+
1305
1397
  .moldable-material[data-material-elevation='panel'] {
1306
1398
  --material-active-shadow: var(--material-shadow-panel);
1307
1399
  }
@@ -0,0 +1,131 @@
1
+ export type UITheme = 'platform' | 'moldable'
2
+
3
+ export type UIPlatform = 'macos' | 'windows' | 'web'
4
+
5
+ export type UIPlatformVersion = string
6
+
7
+ /**
8
+ * A component recipe can intentionally come from a different versioned
9
+ * platform source than the application's base platform pack.
10
+ *
11
+ * Public names describe the anatomy an app is choosing. The registry below
12
+ * records which immutable platform source defines each recipe.
13
+ */
14
+ export type UISidebarStyle = 'platform' | 'floating' | 'edge-to-edge'
15
+
16
+ export type PlatformPackId = `${UIPlatform}-${string}`
17
+
18
+ export interface UIPlatformPack {
19
+ id: PlatformPackId
20
+ platform: UIPlatform
21
+ version: UIPlatformVersion
22
+ capabilities: {
23
+ nativeMaterials: boolean
24
+ nativeWindowChrome: boolean
25
+ overlayScrollbars: boolean
26
+ }
27
+ }
28
+
29
+ export type UIAppearance = 'light' | 'dark' | 'system'
30
+
31
+ export type ResolvedUIAppearance = Exclude<UIAppearance, 'system'>
32
+
33
+ export type ControlSize = 'mini' | 'small' | 'medium' | 'large' | 'xl'
34
+
35
+ export type LayoutDensity = 'compact' | 'regular' | 'comfortable'
36
+
37
+ export type MaterialThickness =
38
+ | 'ultra-thick'
39
+ | 'thick'
40
+ | 'medium'
41
+ | 'thin'
42
+ | 'ultra-thin'
43
+
44
+ export type MaterialContext = 'content' | 'over-glass'
45
+
46
+ export type ContrastPreference = 'system' | 'standard' | 'increased'
47
+
48
+ export type TransparencyPreference = 'system' | 'standard' | 'reduced'
49
+
50
+ export type MotionPreference = 'system' | 'standard' | 'reduced'
51
+
52
+ export interface UIPreferences {
53
+ contrast?: ContrastPreference
54
+ transparency?: TransparencyPreference
55
+ motion?: MotionPreference
56
+ }
57
+
58
+ export const CONTROL_SIZES = [
59
+ 'mini',
60
+ 'small',
61
+ 'medium',
62
+ 'large',
63
+ 'xl',
64
+ ] as const satisfies readonly ControlSize[]
65
+
66
+ export const MATERIAL_THICKNESSES = [
67
+ 'ultra-thick',
68
+ 'thick',
69
+ 'medium',
70
+ 'thin',
71
+ 'ultra-thin',
72
+ ] as const satisfies readonly MaterialThickness[]
73
+
74
+ export const SIDEBAR_STYLES = {
75
+ platform: {
76
+ id: 'platform',
77
+ sourcePlatform: null,
78
+ sourceVersion: null,
79
+ },
80
+ floating: {
81
+ id: 'floating',
82
+ sourcePlatform: 'macos',
83
+ sourceVersion: '26',
84
+ },
85
+ 'edge-to-edge': {
86
+ id: 'edge-to-edge',
87
+ sourcePlatform: 'macos',
88
+ sourceVersion: '27',
89
+ },
90
+ } as const satisfies Record<
91
+ UISidebarStyle,
92
+ {
93
+ id: UISidebarStyle
94
+ sourcePlatform: UIPlatform | null
95
+ sourceVersion: UIPlatformVersion | null
96
+ }
97
+ >
98
+
99
+ export const PLATFORM_PACKS = {
100
+ 'macos-27': {
101
+ id: 'macos-27',
102
+ platform: 'macos',
103
+ version: '27',
104
+ capabilities: {
105
+ nativeMaterials: true,
106
+ nativeWindowChrome: true,
107
+ overlayScrollbars: true,
108
+ },
109
+ },
110
+ 'web-default': {
111
+ id: 'web-default',
112
+ platform: 'web',
113
+ version: 'default',
114
+ capabilities: {
115
+ nativeMaterials: false,
116
+ nativeWindowChrome: false,
117
+ overlayScrollbars: false,
118
+ },
119
+ },
120
+ } as const satisfies Record<string, UIPlatformPack>
121
+
122
+ export function resolvePlatformPack(
123
+ platform: UIPlatform,
124
+ version: UIPlatformVersion,
125
+ ): UIPlatformPack {
126
+ const exact = Object.values(PLATFORM_PACKS).find(
127
+ (pack) => pack.platform === platform && pack.version === version,
128
+ )
129
+
130
+ return exact ?? PLATFORM_PACKS['web-default']
131
+ }