@selvajs/ui 6.6.0-beta.17 → 6.6.0-beta.19

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 (221) hide show
  1. package/dist/components/ErrorScreen.svelte +1 -1
  2. package/dist/components/compute/AppLayout.svelte +2 -2
  3. package/dist/components/compute/ComputeApp.svelte +1 -1
  4. package/dist/components/compute/ComputeApp.svelte.d.ts +1 -1
  5. package/dist/components/compute/ComputeMessagesDialog.svelte +3 -3
  6. package/dist/components/compute/SolveMessages.svelte +3 -3
  7. package/dist/components/layout/AppShell.svelte +1 -1
  8. package/dist/components/layout/FooterItemRenderer.svelte +1 -1
  9. package/dist/components/layout/FooterItemRenderer.svelte.d.ts +1 -1
  10. package/dist/components/layout/PageContent.svelte +3 -2
  11. package/dist/components/layout/PageFooter.svelte +3 -3
  12. package/dist/components/layout/PageHeader.svelte +2 -2
  13. package/dist/components/preview/ChartOutput.svelte +3 -3
  14. package/dist/components/preview/Group.svelte +3 -3
  15. package/dist/components/preview/HelpButton.svelte +1 -1
  16. package/dist/components/preview/ImageOutput.svelte +3 -3
  17. package/dist/components/preview/InputControl.svelte +12 -12
  18. package/dist/components/preview/OutputDisplay.svelte +4 -4
  19. package/dist/components/preview/TabBar.svelte +2 -2
  20. package/dist/components/preview/TabContent.svelte +7 -7
  21. package/dist/components/preview/TabLayout.svelte +3 -3
  22. package/dist/components/preview/inputs/CheckboxInput.svelte +1 -1
  23. package/dist/components/preview/inputs/ChecklistInput.svelte +2 -2
  24. package/dist/components/preview/inputs/ColorInput.svelte +6 -6
  25. package/dist/components/preview/inputs/DropdownInput.svelte +3 -3
  26. package/dist/components/preview/inputs/FileInput.svelte +14 -9
  27. package/dist/components/preview/inputs/GeometryInput.svelte +4 -4
  28. package/dist/components/preview/inputs/GeometryInput.svelte.d.ts +1 -1
  29. package/dist/components/preview/inputs/NumberInput.svelte +8 -8
  30. package/dist/components/preview/inputs/OptionGlyph.svelte +1 -1
  31. package/dist/components/preview/inputs/OptionGlyph.svelte.d.ts +1 -1
  32. package/dist/components/preview/inputs/SegmentedInput.svelte +4 -4
  33. package/dist/components/preview/inputs/TextInput.svelte +5 -5
  34. package/dist/components/preview/inputs/TileInput.svelte +5 -3
  35. package/dist/components/primitives/CalculateButton.svelte +1 -1
  36. package/dist/components/primitives/FilterableDropdown.svelte +13 -1
  37. package/dist/components/primitives/FilterableDropdown.svelte.d.ts +5 -0
  38. package/dist/components/primitives/button/button.svelte +1 -1
  39. package/dist/components/primitives/button/button.svelte.d.ts +1 -1
  40. package/dist/components/primitives/dialog/dialog-content.svelte +1 -1
  41. package/dist/components/primitives/input-group/input-group-input.svelte.d.ts +1 -1
  42. package/dist/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
  43. package/dist/components/primitives/select/select-content.svelte +1 -1
  44. package/dist/components/primitives/tabs/tabs-list.svelte +1 -1
  45. package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +3 -3
  46. package/dist/components/primitives/tabs/tabs-trigger.svelte +1 -1
  47. package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +3 -3
  48. package/dist/components/primitives/toggle/toggle.svelte +1 -1
  49. package/dist/components/primitives/toggle/toggle.svelte.d.ts +3 -3
  50. package/dist/components/viewer/MeshMetadataPanel.svelte +1 -1
  51. package/dist/components/viewer/SceneManager.svelte +1 -1
  52. package/dist/components/viewer/Viewer.svelte +3 -35
  53. package/dist/components/viewer/Viewer.svelte.d.ts +1 -1
  54. package/dist/components/viewer/ViewerDock.svelte +10 -10
  55. package/dist/components/viewer/ViewerDock.svelte.d.ts +1 -1
  56. package/dist/composables/useFooterItem.svelte.d.ts +1 -1
  57. package/dist/composables/useFooterItem.svelte.js +1 -1
  58. package/dist/constants.js +1 -2
  59. package/dist/contexts/hostContext.svelte.d.ts +1 -1
  60. package/dist/index.d.ts +1 -0
  61. package/dist/index.js +1 -0
  62. package/dist/styles/base.css +49 -44
  63. package/package.json +17 -12
  64. package/src/lib/components/ErrorScreen.svelte +1 -1
  65. package/src/lib/components/compute/AppLayout.svelte +3 -3
  66. package/src/lib/components/compute/ComputeApp.svelte +1 -1
  67. package/src/lib/components/compute/ComputeMessagesDialog.svelte +4 -4
  68. package/src/lib/components/compute/SolveMessages.svelte +5 -5
  69. package/src/lib/components/layout/AppShell.svelte +1 -1
  70. package/src/lib/components/layout/FooterItemRenderer.svelte +1 -1
  71. package/src/lib/components/layout/PageContent.svelte +3 -2
  72. package/src/lib/components/layout/PageFooter.svelte +3 -3
  73. package/src/lib/components/layout/PageHeader.svelte +2 -2
  74. package/src/lib/components/layout/SideNav.svelte +1 -1
  75. package/src/lib/components/preview/ChartOutput.svelte +3 -3
  76. package/src/lib/components/preview/Group.svelte +3 -3
  77. package/src/lib/components/preview/HelpButton.svelte +1 -1
  78. package/src/lib/components/preview/ImageOutput.svelte +3 -3
  79. package/src/lib/components/preview/InputControl.svelte +12 -12
  80. package/src/lib/components/preview/OutputDisplay.svelte +4 -4
  81. package/src/lib/components/preview/TabBar.svelte +2 -2
  82. package/src/lib/components/preview/TabContent.svelte +7 -7
  83. package/src/lib/components/preview/TabLayout.svelte +3 -3
  84. package/src/lib/components/preview/inputs/CheckboxInput.svelte +1 -1
  85. package/src/lib/components/preview/inputs/ChecklistInput.svelte +2 -2
  86. package/src/lib/components/preview/inputs/ColorInput.svelte +6 -6
  87. package/src/lib/components/preview/inputs/DropdownInput.svelte +3 -3
  88. package/src/lib/components/preview/inputs/FileInput.svelte +14 -9
  89. package/src/lib/components/preview/inputs/GeometryInput.svelte +4 -4
  90. package/src/lib/components/preview/inputs/NumberInput.svelte +8 -8
  91. package/src/lib/components/preview/inputs/OptionGlyph.svelte +2 -2
  92. package/src/lib/components/preview/inputs/SegmentedInput.svelte +4 -4
  93. package/src/lib/components/preview/inputs/TextInput.svelte +5 -5
  94. package/src/lib/components/preview/inputs/TileInput.svelte +5 -3
  95. package/src/lib/components/primitives/CalculateButton.svelte +1 -1
  96. package/src/lib/components/primitives/Callout.svelte +1 -1
  97. package/src/lib/components/primitives/FilterableDropdown.svelte +14 -2
  98. package/src/lib/components/primitives/IssueList.svelte +1 -1
  99. package/src/lib/components/primitives/SeverityIcon.svelte +1 -1
  100. package/src/lib/components/primitives/StateDisplay.svelte +1 -1
  101. package/src/lib/components/primitives/alert-dialog/alert-dialog-action.svelte +2 -2
  102. package/src/lib/components/primitives/alert-dialog/alert-dialog-cancel.svelte +2 -2
  103. package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
  104. package/src/lib/components/primitives/alert-dialog/alert-dialog-description.svelte +1 -1
  105. package/src/lib/components/primitives/alert-dialog/alert-dialog-footer.svelte +1 -1
  106. package/src/lib/components/primitives/alert-dialog/alert-dialog-header.svelte +1 -1
  107. package/src/lib/components/primitives/alert-dialog/alert-dialog-overlay.svelte +1 -1
  108. package/src/lib/components/primitives/alert-dialog/alert-dialog-title.svelte +1 -1
  109. package/src/lib/components/primitives/badge/badge.svelte +1 -1
  110. package/src/lib/components/primitives/button/button.svelte +1 -1
  111. package/src/lib/components/primitives/button-group/button-group-separator.svelte +2 -2
  112. package/src/lib/components/primitives/button-group/button-group-text.svelte +1 -1
  113. package/src/lib/components/primitives/button-group/button-group.svelte +1 -1
  114. package/src/lib/components/primitives/card/card-content.svelte +1 -1
  115. package/src/lib/components/primitives/card/card-description.svelte +1 -1
  116. package/src/lib/components/primitives/card/card-footer.svelte +1 -1
  117. package/src/lib/components/primitives/card/card-header.svelte +1 -1
  118. package/src/lib/components/primitives/card/card-title.svelte +1 -1
  119. package/src/lib/components/primitives/card/card.svelte +1 -1
  120. package/src/lib/components/primitives/checkbox/checkbox.svelte +1 -1
  121. package/src/lib/components/primitives/command/command-dialog.svelte +2 -2
  122. package/src/lib/components/primitives/command/command-empty.svelte +1 -1
  123. package/src/lib/components/primitives/command/command-group.svelte +1 -1
  124. package/src/lib/components/primitives/command/command-input.svelte +2 -2
  125. package/src/lib/components/primitives/command/command-item.svelte +1 -1
  126. package/src/lib/components/primitives/command/command-link-item.svelte +1 -1
  127. package/src/lib/components/primitives/command/command-list.svelte +1 -1
  128. package/src/lib/components/primitives/command/command-separator.svelte +1 -1
  129. package/src/lib/components/primitives/command/command-shortcut.svelte +1 -1
  130. package/src/lib/components/primitives/command/command.svelte +1 -1
  131. package/src/lib/components/primitives/context-menu/context-menu-checkbox-item.svelte +1 -1
  132. package/src/lib/components/primitives/context-menu/context-menu-content.svelte +1 -1
  133. package/src/lib/components/primitives/context-menu/context-menu-group-heading.svelte +1 -1
  134. package/src/lib/components/primitives/context-menu/context-menu-item.svelte +1 -1
  135. package/src/lib/components/primitives/context-menu/context-menu-label.svelte +1 -1
  136. package/src/lib/components/primitives/context-menu/context-menu-radio-item.svelte +1 -1
  137. package/src/lib/components/primitives/context-menu/context-menu-separator.svelte +1 -1
  138. package/src/lib/components/primitives/context-menu/context-menu-shortcut.svelte +1 -1
  139. package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
  140. package/src/lib/components/primitives/context-menu/context-menu-sub-trigger.svelte +1 -1
  141. package/src/lib/components/primitives/dialog/dialog-content.svelte +2 -2
  142. package/src/lib/components/primitives/dialog/dialog-description.svelte +1 -1
  143. package/src/lib/components/primitives/dialog/dialog-footer.svelte +1 -1
  144. package/src/lib/components/primitives/dialog/dialog-header.svelte +1 -1
  145. package/src/lib/components/primitives/dialog/dialog-overlay.svelte +1 -1
  146. package/src/lib/components/primitives/dialog/dialog-title.svelte +1 -1
  147. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +1 -1
  148. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +1 -1
  149. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
  150. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +1 -1
  151. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-label.svelte +1 -1
  152. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
  153. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-separator.svelte +1 -1
  154. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
  155. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
  156. package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  157. package/src/lib/components/primitives/empty/empty-content.svelte +1 -1
  158. package/src/lib/components/primitives/empty/empty-description.svelte +1 -1
  159. package/src/lib/components/primitives/empty/empty-header.svelte +1 -1
  160. package/src/lib/components/primitives/empty/empty-media.svelte +1 -1
  161. package/src/lib/components/primitives/empty/empty-title.svelte +1 -1
  162. package/src/lib/components/primitives/empty/empty.svelte +1 -1
  163. package/src/lib/components/primitives/field/field-content.svelte +1 -1
  164. package/src/lib/components/primitives/field/field-description.svelte +1 -1
  165. package/src/lib/components/primitives/field/field-error.svelte +1 -1
  166. package/src/lib/components/primitives/field/field-group.svelte +1 -1
  167. package/src/lib/components/primitives/field/field-label.svelte +2 -2
  168. package/src/lib/components/primitives/field/field-legend.svelte +1 -1
  169. package/src/lib/components/primitives/field/field-separator.svelte +2 -2
  170. package/src/lib/components/primitives/field/field-set.svelte +1 -1
  171. package/src/lib/components/primitives/field/field-title.svelte +1 -1
  172. package/src/lib/components/primitives/field/field.svelte +1 -1
  173. package/src/lib/components/primitives/input/input.svelte +1 -1
  174. package/src/lib/components/primitives/input-group/input-group-addon.svelte +1 -1
  175. package/src/lib/components/primitives/input-group/input-group-button.svelte +2 -2
  176. package/src/lib/components/primitives/input-group/input-group-input.svelte +2 -2
  177. package/src/lib/components/primitives/input-group/input-group-text.svelte +1 -1
  178. package/src/lib/components/primitives/input-group/input-group-textarea.svelte +2 -2
  179. package/src/lib/components/primitives/input-group/input-group.svelte +1 -1
  180. package/src/lib/components/primitives/label/label.svelte +1 -1
  181. package/src/lib/components/primitives/mode-toggle/mode-toggle.svelte +2 -2
  182. package/src/lib/components/primitives/popover/popover-content.svelte +1 -1
  183. package/src/lib/components/primitives/popover/popover-description.svelte +1 -1
  184. package/src/lib/components/primitives/popover/popover-header.svelte +1 -1
  185. package/src/lib/components/primitives/popover/popover-title.svelte +1 -1
  186. package/src/lib/components/primitives/popover/popover-trigger.svelte +1 -1
  187. package/src/lib/components/primitives/resizable/resizable-handle.svelte +1 -1
  188. package/src/lib/components/primitives/resizable/resizable-pane-group.svelte +1 -1
  189. package/src/lib/components/primitives/scroll-area/scroll-area-scrollbar.svelte +1 -1
  190. package/src/lib/components/primitives/scroll-area/scroll-area.svelte +1 -1
  191. package/src/lib/components/primitives/search/search.svelte +1 -1
  192. package/src/lib/components/primitives/select/select-content.svelte +2 -2
  193. package/src/lib/components/primitives/select/select-group-heading.svelte +1 -1
  194. package/src/lib/components/primitives/select/select-item.svelte +1 -1
  195. package/src/lib/components/primitives/select/select-label.svelte +1 -1
  196. package/src/lib/components/primitives/select/select-scroll-down-button.svelte +1 -1
  197. package/src/lib/components/primitives/select/select-scroll-up-button.svelte +1 -1
  198. package/src/lib/components/primitives/select/select-separator.svelte +2 -2
  199. package/src/lib/components/primitives/select/select-trigger.svelte +1 -1
  200. package/src/lib/components/primitives/separator/separator.svelte +1 -1
  201. package/src/lib/components/primitives/slider/slider.svelte +1 -1
  202. package/src/lib/components/primitives/spinner/spinner.svelte +1 -1
  203. package/src/lib/components/primitives/switch/switch.svelte +1 -1
  204. package/src/lib/components/primitives/tabs/tabs-content.svelte +1 -1
  205. package/src/lib/components/primitives/tabs/tabs-list.svelte +2 -2
  206. package/src/lib/components/primitives/tabs/tabs-trigger.svelte +2 -2
  207. package/src/lib/components/primitives/tabs/tabs.svelte +1 -1
  208. package/src/lib/components/primitives/textarea/textarea.svelte +1 -1
  209. package/src/lib/components/primitives/toggle/toggle.svelte +2 -2
  210. package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +2 -2
  211. package/src/lib/components/primitives/toggle-group/toggle-group.svelte +2 -2
  212. package/src/lib/components/primitives/tooltip/tooltip-content.svelte +1 -1
  213. package/src/lib/components/viewer/MeshMetadataPanel.svelte +1 -1
  214. package/src/lib/components/viewer/SceneManager.svelte +1 -1
  215. package/src/lib/components/viewer/Viewer.svelte +4 -36
  216. package/src/lib/components/viewer/ViewerDock.svelte +11 -11
  217. package/src/lib/composables/useFooterItem.svelte.ts +1 -1
  218. package/src/lib/constants.ts +1 -2
  219. package/src/lib/contexts/hostContext.svelte.ts +1 -1
  220. package/src/lib/index.ts +1 -0
  221. package/src/lib/styles/base.css +49 -44
@@ -11,6 +11,7 @@
11
11
  label: string;
12
12
  icon?: Component;
13
13
  iconClass?: string;
14
+ disabled?: boolean;
14
15
  }
15
16
 
16
17
  interface Props {
@@ -24,6 +25,10 @@
24
25
  /** Above this many items the list gets a filter box. */
25
26
  searchThreshold?: number;
26
27
  disabled?: boolean;
28
+ /** Submits the picked id with a plain <form>, like a native select's name. */
29
+ name?: string;
30
+ size?: 'default' | 'sm';
31
+ 'aria-label'?: string;
27
32
  class?: string;
28
33
  }
29
34
 
@@ -37,6 +42,9 @@
37
42
  searchPlaceholder = 'Filter...',
38
43
  searchThreshold = 4,
39
44
  disabled = false,
45
+ name,
46
+ size = 'default',
47
+ 'aria-label': ariaLabel,
40
48
  class: className
41
49
  }: Props = $props();
42
50
 
@@ -51,14 +59,17 @@
51
59
  }
52
60
  </script>
53
61
 
62
+ {#if name}<input type="hidden" {name} value={value ?? ''} />{/if}
63
+
54
64
  <Popover.Root bind:open>
55
65
  <Popover.Trigger
56
66
  {id}
57
67
  {disabled}
58
68
  role="combobox"
59
69
  aria-expanded={open}
70
+ aria-label={ariaLabel}
60
71
  class={cn(
61
- buttonVariants({ variant: 'outline' }),
72
+ buttonVariants({ variant: 'outline', size }),
62
73
  'font-normal w-full justify-start',
63
74
  className
64
75
  )}
@@ -85,6 +96,7 @@
85
96
  value={item.id}
86
97
  keywords={[item.label]}
87
98
  data-checked={item.id === value}
99
+ disabled={item.disabled}
88
100
  onSelect={() => pick(item)}
89
101
  >
90
102
  {#if ItemIcon}
@@ -4,6 +4,7 @@ export interface FilterableDropdownItem {
4
4
  label: string;
5
5
  icon?: Component;
6
6
  iconClass?: string;
7
+ disabled?: boolean;
7
8
  }
8
9
  interface Props {
9
10
  items: FilterableDropdownItem[];
@@ -16,6 +17,10 @@ interface Props {
16
17
  /** Above this many items the list gets a filter box. */
17
18
  searchThreshold?: number;
18
19
  disabled?: boolean;
20
+ /** Submits the picked id with a plain <form>, like a native select's name. */
21
+ name?: string;
22
+ size?: 'default' | 'sm';
23
+ 'aria-label'?: string;
19
24
  class?: string;
20
25
  }
21
26
  declare const FilterableDropdown: Component<Props, {}, "">;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts" module>
2
- import { cn, type WithElementRef } from '../../../utils';
2
+ import { cn, type WithElementRef } from '../../../utils.js';
3
3
  import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
4
4
  import { type VariantProps, tv } from 'tailwind-variants';
5
5
 
@@ -1,4 +1,4 @@
1
- import { type WithElementRef } from '../../../utils';
1
+ import { type WithElementRef } from '../../../utils.js';
2
2
  import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
3
  import { type VariantProps } from 'tailwind-variants';
4
4
  export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
@@ -4,7 +4,7 @@
4
4
  import type { Snippet } from 'svelte';
5
5
  import * as Dialog from './index.js';
6
6
  import { cn, type WithoutChildrenOrChild } from '../../../utils.js';
7
- import { getLocaleContext } from '../../../i18n/localeContext.svelte';
7
+ import { getLocaleContext } from '../../../i18n/localeContext.svelte.js';
8
8
 
9
9
  let {
10
10
  ref = $bindable(null),
@@ -2,7 +2,7 @@ declare const InputGroupInput: import("svelte").Component<(Omit<import("svelte/e
2
2
  type: "file";
3
3
  files?: FileList;
4
4
  } | {
5
- type?: "number" | "submit" | "reset" | "button" | "search" | "checkbox" | "radio" | (string & {}) | "text" | "tel" | "url" | "email" | "hidden" | "color" | "date" | "time" | "datetime-local" | "image" | "month" | "password" | "range" | "week";
5
+ type?: "number" | "submit" | "reset" | "button" | "search" | "checkbox" | "radio" | (string & {}) | "text" | "tel" | "url" | "email" | "hidden" | "color" | "date" | "datetime-local" | "image" | "month" | "password" | "range" | "time" | "week";
6
6
  files?: undefined;
7
7
  })) & {
8
8
  ref?: HTMLElement | null | undefined;
@@ -2,8 +2,8 @@
2
2
  import Sun from '@lucide/svelte/icons/sun';
3
3
  import Moon from '@lucide/svelte/icons/moon';
4
4
  import { toggleMode } from 'mode-watcher';
5
- import { Button } from '../button';
6
- import { getLocaleContext } from '../../../i18n/localeContext.svelte';
5
+ import { Button } from '../button/index.js';
6
+ import { getLocaleContext } from '../../../i18n/localeContext.svelte.js';
7
7
 
8
8
  const locale = getLocaleContext();
9
9
  </script>
@@ -22,7 +22,7 @@
22
22
  {sideOffset}
23
23
  data-slot="select-content"
24
24
  class={cn(
25
- 'data-[side=bottom]:translate-y-1 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:-translate-x-1 data-[side=left]:slide-in-from-right-2 data-[side=right]:translate-x-1 data-[side=right]:slide-in-from-left-2 data-[side=top]:-translate-y-1 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 min-w-32 relative z-50 max-h-(--bits-select-content-available-height) origin-(--bits-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-border-strong bg-popover text-popover-foreground shadow-popover',
25
+ 'data-[side=bottom]:translate-y-1 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:-translate-x-1 data-[side=left]:slide-in-from-right-2 data-[side=right]:translate-x-1 data-[side=right]:slide-in-from-left-2 data-[side=top]:-translate-y-1 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 min-w-32 max-h-96 relative z-50 origin-(--bits-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-border-strong bg-popover text-popover-foreground shadow-popover',
26
26
  className
27
27
  )}
28
28
  {...restProps}
@@ -6,7 +6,7 @@
6
6
  variants: {
7
7
  variant: {
8
8
  default: 'h-9 w-fit justify-center rounded-md bg-muted p-0.5',
9
- line: 'gap-1 px-2 w-full justify-start'
9
+ line: 'gap-1 px-1 w-full justify-start'
10
10
  }
11
11
  },
12
12
  defaultVariants: {
@@ -2,17 +2,17 @@ import { type VariantProps } from 'tailwind-variants';
2
2
  export declare const tabsListVariants: import("tailwind-variants").TVReturnType<{
3
3
  variant: {
4
4
  default: "h-9 w-fit justify-center rounded-md bg-muted p-0.5";
5
- line: "gap-1 px-2 w-full justify-start";
5
+ line: "gap-1 px-1 w-full justify-start";
6
6
  };
7
7
  }, undefined, "inline-flex items-center text-muted-foreground", {
8
8
  variant: {
9
9
  default: "h-9 w-fit justify-center rounded-md bg-muted p-0.5";
10
- line: "gap-1 px-2 w-full justify-start";
10
+ line: "gap-1 px-1 w-full justify-start";
11
11
  };
12
12
  }, undefined, import("tailwind-variants").TVReturnTypeLike<{
13
13
  variant: {
14
14
  default: "h-9 w-fit justify-center rounded-md bg-muted p-0.5";
15
- line: "gap-1 px-2 w-full justify-start";
15
+ line: "gap-1 px-1 w-full justify-start";
16
16
  };
17
17
  }, undefined>>;
18
18
  export type TabsListVariant = VariantProps<typeof tabsListVariants>['variant'];
@@ -7,7 +7,7 @@
7
7
  variant: {
8
8
  default:
9
9
  'px-2 py-1 data-[state=active]:shadow-sm h-full flex-1 rounded-inner border border-transparent text-foreground transition focus-visible:border-ring data-[state=active]:bg-raised dark:text-muted-foreground data-[state=active]:border-border-strong dark:data-[state=active]:text-foreground',
10
- line: 'px-2.5 py-3 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary'
10
+ line: 'px-2.5 py-2.5 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary'
11
11
  }
12
12
  },
13
13
  defaultVariants: {
@@ -2,17 +2,17 @@ import { type VariantProps } from 'tailwind-variants';
2
2
  export declare const tabsTriggerVariants: import("tailwind-variants").TVReturnType<{
3
3
  variant: {
4
4
  default: "px-2 py-1 data-[state=active]:shadow-sm h-full flex-1 rounded-inner border border-transparent text-foreground transition focus-visible:border-ring data-[state=active]:bg-raised dark:text-muted-foreground data-[state=active]:border-border-strong dark:data-[state=active]:text-foreground";
5
- line: "px-2.5 py-3 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary";
5
+ line: "px-2.5 py-2.5 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary";
6
6
  };
7
7
  }, undefined, "gap-1.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", {
8
8
  variant: {
9
9
  default: "px-2 py-1 data-[state=active]:shadow-sm h-full flex-1 rounded-inner border border-transparent text-foreground transition focus-visible:border-ring data-[state=active]:bg-raised dark:text-muted-foreground data-[state=active]:border-border-strong dark:data-[state=active]:text-foreground";
10
- line: "px-2.5 py-3 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary";
10
+ line: "px-2.5 py-2.5 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary";
11
11
  };
12
12
  }, undefined, import("tailwind-variants").TVReturnTypeLike<{
13
13
  variant: {
14
14
  default: "px-2 py-1 data-[state=active]:shadow-sm h-full flex-1 rounded-inner border border-transparent text-foreground transition focus-visible:border-ring data-[state=active]:bg-raised dark:text-muted-foreground data-[state=active]:border-border-strong dark:data-[state=active]:text-foreground";
15
- line: "px-2.5 py-3 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary";
15
+ line: "px-2.5 py-2.5 relative flex-none text-muted-foreground transition-colors after:absolute after:inset-x-2 after:bottom-0 after:h-0.5 after:rounded-full hover:text-foreground data-[state=active]:text-foreground data-[state=active]:after:bg-primary";
16
16
  };
17
17
  }, undefined>>;
18
18
  export type TabsTriggerVariant = VariantProps<typeof tabsTriggerVariants>['variant'];
@@ -9,7 +9,7 @@
9
9
  // Item inside a segmented track: the chosen value sits raised above the track.
10
10
  segmented:
11
11
  'rounded-inner bg-transparent text-muted-foreground data-[state=on]:bg-raised data-[state=on]:text-foreground data-[state=on]:shadow-raised data-[state=on]:ring-1 data-[state=on]:ring-border-strong',
12
- outline: 'border-input hover:bg-hover border bg-transparent',
12
+ outline: 'border-input hover:bg-hover border bg-field',
13
13
  // Filled accent for the active item; a bare bg-muted is too faint on a form.
14
14
  accent:
15
15
  'border-input hover:bg-hover border bg-transparent data-[state=on]:bg-primary/15 data-[state=on]:ring-1 data-[state=on]:ring-primary data-[state=on]:ring-inset'
@@ -3,7 +3,7 @@ export declare const toggleVariants: import("tailwind-variants").TVReturnType<{
3
3
  variant: {
4
4
  default: "bg-transparent";
5
5
  segmented: "rounded-inner bg-transparent text-muted-foreground data-[state=on]:bg-raised data-[state=on]:text-foreground data-[state=on]:shadow-raised data-[state=on]:ring-1 data-[state=on]:ring-border-strong";
6
- outline: "border-input hover:bg-hover border bg-transparent";
6
+ outline: "border-input hover:bg-hover border bg-field";
7
7
  accent: "border-input hover:bg-hover border bg-transparent data-[state=on]:bg-primary/15 data-[state=on]:ring-1 data-[state=on]:ring-primary data-[state=on]:ring-inset";
8
8
  };
9
9
  size: {
@@ -16,7 +16,7 @@ export declare const toggleVariants: import("tailwind-variants").TVReturnType<{
16
16
  variant: {
17
17
  default: "bg-transparent";
18
18
  segmented: "rounded-inner bg-transparent text-muted-foreground data-[state=on]:bg-raised data-[state=on]:text-foreground data-[state=on]:shadow-raised data-[state=on]:ring-1 data-[state=on]:ring-border-strong";
19
- outline: "border-input hover:bg-hover border bg-transparent";
19
+ outline: "border-input hover:bg-hover border bg-field";
20
20
  accent: "border-input hover:bg-hover border bg-transparent data-[state=on]:bg-primary/15 data-[state=on]:ring-1 data-[state=on]:ring-primary data-[state=on]:ring-inset";
21
21
  };
22
22
  size: {
@@ -29,7 +29,7 @@ export declare const toggleVariants: import("tailwind-variants").TVReturnType<{
29
29
  variant: {
30
30
  default: "bg-transparent";
31
31
  segmented: "rounded-inner bg-transparent text-muted-foreground data-[state=on]:bg-raised data-[state=on]:text-foreground data-[state=on]:shadow-raised data-[state=on]:ring-1 data-[state=on]:ring-border-strong";
32
- outline: "border-input hover:bg-hover border bg-transparent";
32
+ outline: "border-input hover:bg-hover border bg-field";
33
33
  accent: "border-input hover:bg-hover border bg-transparent data-[state=on]:bg-primary/15 data-[state=on]:ring-1 data-[state=on]:ring-primary data-[state=on]:ring-inset";
34
34
  };
35
35
  size: {
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { X } from '@lucide/svelte';
3
3
  import { Button } from '../primitives/button/index.js';
4
- import { getLocaleContext } from '../../i18n/localeContext.svelte';
4
+ import { getLocaleContext } from '../../i18n/localeContext.svelte.js';
5
5
 
6
6
  const locale = getLocaleContext();
7
7
  const t = $derived(locale.messages);
@@ -14,7 +14,7 @@
14
14
  type SceneEntry,
15
15
  type SceneOutliner
16
16
  } from '@selvajs/visualization/scene';
17
- import { getLocaleContext } from '../../i18n/localeContext.svelte';
17
+ import { getLocaleContext } from '../../i18n/localeContext.svelte.js';
18
18
 
19
19
  const locale = getLocaleContext();
20
20
  const t = $derived(locale.messages);
@@ -24,9 +24,9 @@
24
24
  import ViewerDock from './ViewerDock.svelte';
25
25
  import MeshMetadataPanel from './MeshMetadataPanel.svelte';
26
26
  import * as Resizable from '../primitives/resizable/index.js';
27
- import type { Locale } from '../../i18n/messages';
28
- import { layerLocaleContext } from '../../i18n/localeContext.svelte';
29
- import { saveBlob } from '../../utils/host-files';
27
+ import type { Locale } from '../../i18n/messages.js';
28
+ import { layerLocaleContext } from '../../i18n/localeContext.svelte.js';
29
+ import { saveBlob } from '../../utils/host-files.js';
30
30
 
31
31
  export interface ViewerConfig {
32
32
  showScreenshotButton?: boolean;
@@ -85,7 +85,6 @@
85
85
  let {
86
86
  meshes,
87
87
  isFullscreen = $bindable(false),
88
- isSolving = false,
89
88
  isSlow = false,
90
89
  isBlurred = false,
91
90
  drawerOpen = false,
@@ -525,16 +524,6 @@
525
524
  : 'blur-overlay-inactive'}"
526
525
  ></div>
527
526
 
528
- <!-- The last result stays sharp while the next one solves: blurring it on every
529
- solve hides the model the user is adjusting. -->
530
- {#if isSolving}
531
- <div
532
- class="inset-x-0 top-0 animate-in fade-in pointer-events-none absolute z-20 h-px overflow-hidden duration-300"
533
- aria-hidden="true"
534
- >
535
- <div class="solve-bar h-full w-1/3 bg-faint-foreground"></div>
536
- </div>
537
- {/if}
538
527
  {#if isSlow}
539
528
  <div
540
529
  class="inset-0 animate-in fade-in pointer-events-none absolute z-10 bg-background/25 duration-500"
@@ -633,27 +622,6 @@
633
622
  -webkit-tap-highlight-color: transparent;
634
623
  }
635
624
 
636
- .solve-bar {
637
- animation: solve-bar 1.2s cubic-bezier(0.65, 0, 0.35, 1) infinite;
638
- }
639
-
640
- @keyframes solve-bar {
641
- from {
642
- transform: translateX(-100%);
643
- }
644
- to {
645
- transform: translateX(300%);
646
- }
647
- }
648
-
649
- @media (prefers-reduced-motion: reduce) {
650
- .solve-bar {
651
- animation: none;
652
- width: 100%;
653
- opacity: 0.6;
654
- }
655
- }
656
-
657
625
  .blur-overlay {
658
626
  pointer-events: none;
659
627
  }
@@ -1,5 +1,5 @@
1
1
  import { type Look, type ThreeViewer } from '@selvajs/visualization/render';
2
- import type { Locale } from '../../i18n/messages';
2
+ import type { Locale } from '../../i18n/messages.js';
3
3
  export interface ViewerConfig {
4
4
  showScreenshotButton?: boolean;
5
5
  showFullscreenButton?: boolean;
@@ -17,7 +17,7 @@
17
17
  } from '@lucide/svelte';
18
18
  import type { CameraProjection, Look, ViewPreset } from '@selvajs/visualization/render';
19
19
  import * as DropdownMenu from '../primitives/dropdown-menu/index.js';
20
- import type { ViewerMessages } from '../../i18n/messages';
20
+ import type { ViewerMessages } from '../../i18n/messages.js';
21
21
 
22
22
  interface Props {
23
23
  t: ViewerMessages;
@@ -87,8 +87,8 @@
87
87
  const touch = new MediaQuery('(pointer: coarse)');
88
88
  const reducedMotion = new MediaQuery('(prefers-reduced-motion: reduce)');
89
89
 
90
- const COLLAPSED = $derived(touch.current ? { w: 44, h: 44 } : { w: 72, h: 8 });
91
- const EXPANDED_H = $derived(touch.current ? 54 : 46);
90
+ const COLLAPSED = $derived(touch.current ? { w: 44, h: 44 } : { w: 56, h: 5 });
91
+ const EXPANDED_H = $derived(touch.current ? 54 : 42);
92
92
  const PAD = 4;
93
93
 
94
94
  let dockEl: HTMLDivElement | undefined = $state();
@@ -108,7 +108,7 @@
108
108
  const containerStyle = $derived.by(() => {
109
109
  const bottom = touch.current ? 'max(1rem,env(safe-area-inset-bottom))' : '0.75rem';
110
110
  const geometry = wantOpen
111
- ? `width:${rowWidth + PAD * 2 + 2}px;height:${EXPANDED_H}px;border-radius:14px;padding:${PAD}px`
111
+ ? `width:${rowWidth + PAD * 2 + 2}px;height:${EXPANDED_H}px;border-radius:12px;padding:${PAD}px`
112
112
  : `width:${COLLAPSED.w}px;height:${COLLAPSED.h}px;border-radius:${touch.current ? 22 : 99}px;padding:0px`;
113
113
  const size = `bottom:${bottom};${geometry}`;
114
114
  if (reducedMotion.current) return size;
@@ -195,7 +195,7 @@
195
195
  const idx = (id: string) => buttons.indexOf(id);
196
196
 
197
197
  const BTN =
198
- 'relative grid size-9.5 shrink-0 place-items-center rounded-lg text-muted-foreground outline-none transition-colors hover:bg-hover hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring aria-pressed:text-foreground data-[state=open]:bg-selected data-[state=open]:text-foreground pointer-coarse:size-11';
198
+ 'relative grid size-8.5 shrink-0 place-items-center rounded-lg text-foreground outline-none transition-colors hover:bg-hover hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring aria-pressed:text-foreground data-[state=open]:bg-selected data-[state=open]:text-foreground pointer-coarse:size-11';
199
199
  const DOT =
200
200
  'aria-pressed:after:absolute aria-pressed:after:bottom-0.5 aria-pressed:after:size-1 aria-pressed:after:rounded-full aria-pressed:after:bg-primary';
201
201
  </script>
@@ -210,15 +210,15 @@
210
210
  role="toolbar"
211
211
  aria-label={t.toolsMenu}
212
212
  tabindex="-1"
213
- class="shadow-lg backdrop-blur-md absolute left-1/2 z-50 -translate-x-1/2 overflow-hidden border {hidden
213
+ class="backdrop-blur-md absolute left-1/2 z-50 -translate-x-1/2 overflow-hidden transition-colors {hidden
214
214
  ? 'pointer-events-none opacity-0'
215
215
  : ''} {wantOpen
216
- ? 'bg-background/70'
216
+ ? 'shadow-md border border-border-strong bg-card/75'
217
217
  : touch.current
218
- ? 'cursor-pointer border-border bg-background/90'
218
+ ? 'shadow-lg cursor-pointer border border-border bg-background/90'
219
219
  : nightOn
220
- ? 'border-white/50 bg-white/40 hover:bg-white/65 cursor-pointer'
221
- : 'cursor-pointer border-border-strong bg-faint-foreground hover:bg-muted-foreground'}"
220
+ ? 'border-white/25 bg-white/35 hover:bg-white/70 cursor-pointer border'
221
+ : 'shadow-sm cursor-pointer border border-border-strong bg-card/90 hover:bg-card'}"
222
222
  style={containerStyle}
223
223
  onclick={openFromCollapsed}
224
224
  onkeydown={(e) => (e.key === 'Escape' ? (engaged = false) : undefined)}
@@ -1,5 +1,5 @@
1
1
  import type { CameraProjection, Look, ViewPreset } from '@selvajs/visualization/render';
2
- import type { ViewerMessages } from '../../i18n/messages';
2
+ import type { ViewerMessages } from '../../i18n/messages.js';
3
3
  interface Props {
4
4
  t: ViewerMessages;
5
5
  /** Fades the dock out while a host drawer covers the viewer. */
@@ -1,5 +1,5 @@
1
1
  import { type Component } from 'svelte';
2
- import { type FooterItem } from '../contexts/footerContext.svelte';
2
+ import { type FooterItem } from '../contexts/footerContext.svelte.js';
3
3
  export type FooterItemConfig<P extends Record<string, unknown> = Record<string, unknown>> = Omit<FooterItem<P>, 'position' | 'priority'> & Partial<Pick<FooterItem<P>, 'position' | 'priority'>>;
4
4
  /**
5
5
  * Register a footer item for the lifetime of the calling component.
@@ -1,5 +1,5 @@
1
1
  import { getContext, onMount, onDestroy } from 'svelte';
2
- import { FOOTER_CONTEXT_KEY } from '../contexts/footerContext.svelte';
2
+ import { FOOTER_CONTEXT_KEY } from '../contexts/footerContext.svelte.js';
3
3
  /**
4
4
  * Register a footer item for the lifetime of the calling component.
5
5
  *
package/dist/constants.js CHANGED
@@ -1,8 +1,7 @@
1
1
  export const APP_DEFAULTS = {
2
2
  // File upload limits
3
3
  // TEMP (dev): raised 150 MB → 300 MB so large dev file-widget inputs aren't
4
- // blocked client-side. The server request cap (COMPUTE_REQUEST_MAX_BYTES)
5
- // still defaults to 256 MB, and base64 inflates a raw file by ~4/3, so
4
+ // blocked client-side. The server request cap is 256 MB, and base64 inflates a raw file by ~4/3, so
6
5
  // anything over ~192 MB is rejected with a 413 after the client accepts it.
7
6
  // Revert to 150 before release.
8
7
  FILE_UPLOAD: {
@@ -1,5 +1,5 @@
1
1
  import type { GeometryKind } from '@selvajs/schemas';
2
- import type { UIHost } from '../schema/host-support';
2
+ import type { UIHost } from '../schema/host-support.js';
3
3
  export type GeometryPickResult = {
4
4
  outcome: 'picked';
5
5
  summary: string;
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { default as SolveMessages } from './components/compute/SolveMessages.sve
5
5
  export { default as ErrorScreen } from './components/ErrorScreen.svelte';
6
6
  export * from './components/primitives';
7
7
  export { default as StateDisplay } from './components/primitives/StateDisplay.svelte';
8
+ export { default as ColorInput } from './components/preview/inputs/ColorInput.svelte';
8
9
  export { default as Viewer } from './components/viewer/Viewer.svelte';
9
10
  export * from './schema/defaults';
10
11
  export * from './schema/dynamic-value-list';
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ export { default as ErrorScreen } from './components/ErrorScreen.svelte';
9
9
  // Design-system primitives (shadcn-svelte + custom)
10
10
  export * from './components/primitives';
11
11
  export { default as StateDisplay } from './components/primitives/StateDisplay.svelte';
12
+ export { default as ColorInput } from './components/preview/inputs/ColorInput.svelte';
12
13
  export { default as Viewer } from './components/viewer/Viewer.svelte';
13
14
  export * from './schema/defaults';
14
15
  export * from './schema/dynamic-value-list';
@@ -1,3 +1,5 @@
1
+ @import '@fontsource-variable/hanken-grotesk';
2
+
1
3
  @custom-variant dark (&:where(.dark, .dark *));
2
4
 
3
5
  /* Surfaces, edges and states share one set of names in both modes; each mode only changes the
@@ -8,40 +10,41 @@
8
10
  --page-px: 1rem;
9
11
  --page-py: 1.75rem;
10
12
  /* Canvas, then surface (cards, panels), then raised (rows, menus, popovers). Light can't go
11
- lighter than white, so raised is white too and lifts with a border and a shadow instead. */
12
- --background: oklch(0.91 0 0);
13
+ lighter than white, so raised is white too and lifts with a border and a shadow instead.
14
+ Values follow stock shadcn neutral. */
15
+ --background: oklch(0.985 0 0);
13
16
  --card: oklch(1 0 0);
14
17
  --raised: oklch(1 0 0);
15
18
  /* Recessed fill for trays, table heads, code and skeletons: darker than the surface around it. */
16
- --muted: oklch(0.94 0 0);
17
- /* Fill of anything you type into, on a card: the same step as raised, in both modes. The edge
18
- (`--input`) carries the boundary. A recessed fill reads as a disabled control. */
19
- --field: var(--raised);
20
- --foreground: oklch(0.22 0 0);
21
- --card-foreground: oklch(0.22 0 0);
22
- --popover-foreground: oklch(0.22 0 0);
19
+ --muted: oklch(0.97 0 0);
20
+ /* Fill of anything you type into, on a card: recessed, the same step as muted, in both modes.
21
+ The edge (`--input`) carries the boundary. */
22
+ --field: var(--muted);
23
+ --foreground: oklch(0.145 0 0);
24
+ --card-foreground: oklch(0.145 0 0);
25
+ --popover-foreground: oklch(0.145 0 0);
23
26
  /* 4.5:1 on every surface. */
24
- --muted-foreground: oklch(0.48 0 0);
27
+ --muted-foreground: oklch(0.5 0 0);
25
28
  /* Icons, placeholders, disabled text: 3:1 on every surface. */
26
29
  --faint-foreground: oklch(0.6 0 0);
27
30
  /* State overlays, laid over whatever surface is underneath. */
28
- --hover: oklch(0 0 0 / 6%);
29
- --selected: oklch(0 0 0 / 12%);
31
+ --hover: oklch(0 0 0 / 4%);
32
+ --selected: oklch(0 0 0 / 8%);
30
33
  /* Rest fill of a neutral filled control; its hover is `selected`. */
31
- --secondary: oklch(0 0 0 / 7%);
32
- --secondary-foreground: oklch(0.22 0 0);
34
+ --secondary: oklch(0.97 0 0);
35
+ --secondary-foreground: oklch(0.205 0 0);
33
36
  /* Outlines and separators. */
34
- --border: oklch(0 0 0 / 11%);
37
+ --border: oklch(0 0 0 / 8%);
35
38
  /* Popovers, outline buttons, dashed drop zones. */
36
- --border-strong: oklch(0 0 0 / 24%);
37
- /* Edge of anything you type into or toggle, slider tracks included: at least 3:1 against the
38
- surfaces around it, the WCAG minimum for a control's boundary. */
39
- --input: oklch(0 0 0 / 44%);
40
- --ring: oklch(0.55 0 0);
41
- --elevation-raised: 0 1px 2px oklch(0 0 0 / 6%);
42
- --elevation-popover: 0 8px 24px oklch(0 0 0 / 12%);
39
+ --border-strong: oklch(0 0 0 / 14%);
40
+ /* Edge of anything you type into or toggle, slider tracks included. Softer than the 3:1 WCAG
41
+ boundary minimum in both modes: the recessed field fill carries the rest of the boundary. */
42
+ --input: oklch(0 0 0 / 10%);
43
+ --ring: oklch(0.708 0 0);
44
+ --elevation-raised: 0 1px 2px oklch(0 0 0 / 5%);
45
+ --elevation-popover: 0 8px 24px oklch(0 0 0 / 10%);
43
46
  /* 4.5:1 as text on a card and under its foreground; 3:1 as a fill on every surface. */
44
- --primary: #4a7c52;
47
+ --primary: oklch(0.205 0 0);
45
48
  --primary-foreground: oklch(0.985 0 0);
46
49
  --destructive: #c9302d;
47
50
  --destructive-foreground: #fbfbfb;
@@ -62,28 +65,28 @@
62
65
  }
63
66
 
64
67
  .dark {
65
- --background: oklch(0.155 0 0);
66
- --card: oklch(0.235 0 0);
67
- --raised: oklch(0.275 0 0);
68
- --muted: oklch(0.18 0 0);
69
- --foreground: oklch(0.96 0 0);
70
- --card-foreground: oklch(0.96 0 0);
71
- --popover-foreground: oklch(0.96 0 0);
72
- --muted-foreground: oklch(0.72 0 0);
73
- --faint-foreground: oklch(0.56 0 0);
68
+ --background: oklch(0.145 0 0);
69
+ --card: oklch(0.205 0 0);
70
+ --raised: oklch(0.24 0 0);
71
+ --muted: oklch(0.269 0 0);
72
+ --foreground: oklch(0.985 0 0);
73
+ --card-foreground: oklch(0.985 0 0);
74
+ --popover-foreground: oklch(0.985 0 0);
75
+ --muted-foreground: oklch(0.708 0 0);
76
+ --faint-foreground: oklch(0.556 0 0);
74
77
  --hover: oklch(1 0 0 / 6%);
75
- --selected: oklch(1 0 0 / 12%);
76
- --secondary: oklch(1 0 0 / 8%);
77
- --secondary-foreground: oklch(0.96 0 0);
78
- --border: oklch(1 0 0 / 11%);
79
- --border-strong: oklch(1 0 0 / 24%);
80
- --input: oklch(1 0 0 / 41%);
81
- --ring: oklch(0.74 0 0);
82
- /* Shadows barely show on a dark canvas, so raised things catch a top highlight instead. */
83
- --elevation-raised: inset 0 1px 0 oklch(1 0 0 / 5%);
84
- --elevation-popover: 0 8px 24px oklch(0 0 0 / 50%), inset 0 1px 0 oklch(1 0 0 / 6%);
85
- --primary: #86ab78;
86
- --primary-foreground: oklch(0.18 0 0);
78
+ --selected: oklch(1 0 0 / 10%);
79
+ --secondary: oklch(0.269 0 0);
80
+ --secondary-foreground: oklch(0.985 0 0);
81
+ --border: oklch(1 0 0 / 10%);
82
+ --border-strong: oklch(1 0 0 / 18%);
83
+ --input: oklch(1 0 0 / 15%);
84
+ --ring: oklch(0.556 0 0);
85
+ /* Shadows barely show on a dark canvas, so raised things lean on the border instead. */
86
+ --elevation-raised: none;
87
+ --elevation-popover: 0 8px 24px oklch(0 0 0 / 50%);
88
+ --primary: oklch(0.922 0 0);
89
+ --primary-foreground: oklch(0.205 0 0);
87
90
  /* White text can't reach 4.5:1 on a red light enough to also be text on the dark card. */
88
91
  --destructive: oklch(0.7 0.17 22);
89
92
  --destructive-foreground: oklch(0.18 0 0);
@@ -151,6 +154,8 @@
151
154
  /* Design tokens beyond Tailwind's defaults. Reach for these before an arbitrary value: the
152
155
  design-system lint rejects `text-[10px]`, `max-h-[85dvh]` and the like. */
153
156
  @theme {
157
+ /* Hanken Grotesk (OFL), self-hosted via Fontsource: the plugin UI runs offline from the .gha. */
158
+ --font-sans: 'Hanken Grotesk Variable', ui-sans-serif, system-ui, sans-serif;
154
159
  /* Type tags, counters and other dense labels. */
155
160
  --text-2xs: 0.625rem;
156
161
  --text-2xs--line-height: calc(0.875 / 0.625);