@nqmcreative/ui 0.1.1 → 0.2.1

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 (308) hide show
  1. package/README.md +89 -34
  2. package/cli/index.mjs +83 -33
  3. package/dist/core/calendar.d.ts +3 -0
  4. package/dist/core/calendar.js +36 -0
  5. package/dist/core/dialog.svelte.d.ts +14 -0
  6. package/dist/core/dialog.svelte.js +23 -0
  7. package/dist/core/files.d.ts +35 -0
  8. package/dist/core/files.js +62 -0
  9. package/dist/core/index.d.ts +37 -0
  10. package/dist/core/index.js +35 -0
  11. package/dist/core/list.svelte.d.ts +41 -0
  12. package/dist/core/list.svelte.js +77 -0
  13. package/dist/core/number.d.ts +7 -0
  14. package/dist/core/number.js +17 -0
  15. package/dist/core/pagination.d.ts +6 -0
  16. package/dist/core/pagination.js +21 -0
  17. package/dist/core/password.d.ts +8 -0
  18. package/dist/core/password.js +23 -0
  19. package/dist/core/table.d.ts +22 -0
  20. package/dist/core/table.js +41 -0
  21. package/dist/core/theme.svelte.d.ts +16 -0
  22. package/dist/core/theme.svelte.js +34 -0
  23. package/dist/core/trigger.d.ts +35 -0
  24. package/dist/core/trigger.js +77 -0
  25. package/dist/index.d.ts +11 -103
  26. package/dist/index.js +11 -75
  27. package/dist/{components → styles/matte}/AccordionItem.svelte +1 -1
  28. package/dist/{components → styles/matte}/AccordionItem.svelte.d.ts +1 -1
  29. package/dist/{components → styles/matte}/Alert.svelte +8 -2
  30. package/dist/{components → styles/matte}/Alert.svelte.d.ts +1 -1
  31. package/dist/{components → styles/matte}/Avatar.svelte +1 -1
  32. package/dist/{components → styles/matte}/Avatar.svelte.d.ts +1 -1
  33. package/dist/{components → styles/matte}/Badge.svelte +8 -3
  34. package/dist/{components → styles/matte}/Badge.svelte.d.ts +1 -3
  35. package/dist/{components → styles/matte}/Breadcrumb.svelte +2 -2
  36. package/dist/{components → styles/matte}/Breadcrumb.svelte.d.ts +1 -1
  37. package/dist/{components → styles/matte}/Button.svelte +1 -1
  38. package/dist/{components → styles/matte}/Button.svelte.d.ts +1 -1
  39. package/dist/styles/matte/CTASection.svelte +76 -0
  40. package/dist/styles/matte/CTASection.svelte.d.ts +18 -0
  41. package/dist/{components → styles/matte}/Calendar.svelte +7 -17
  42. package/dist/{components → styles/matte}/Calendar.svelte.d.ts +1 -1
  43. package/dist/{components → styles/matte}/Card.svelte +1 -1
  44. package/dist/{components → styles/matte}/Card.svelte.d.ts +1 -1
  45. package/dist/{components → styles/matte}/Checkbox.svelte +1 -1
  46. package/dist/{components → styles/matte}/Checkbox.svelte.d.ts +1 -1
  47. package/dist/{components → styles/matte}/CheckboxGroup.svelte +1 -1
  48. package/dist/{components → styles/matte}/CheckboxGroup.svelte.d.ts +1 -1
  49. package/dist/{components → styles/matte}/Combobox.svelte +31 -42
  50. package/dist/{components → styles/matte}/Combobox.svelte.d.ts +1 -1
  51. package/dist/{components → styles/matte}/CommandPalette.svelte +26 -41
  52. package/dist/{components → styles/matte}/CommandPalette.svelte.d.ts +1 -1
  53. package/dist/{components → styles/matte}/ConfirmDialog.svelte +2 -2
  54. package/dist/{components → styles/matte}/ConfirmDialog.svelte.d.ts +2 -2
  55. package/dist/{components → styles/matte}/ContextMenu.svelte +5 -7
  56. package/dist/{components → styles/matte}/DatePicker.svelte +7 -11
  57. package/dist/{components → styles/matte}/DatePicker.svelte.d.ts +1 -1
  58. package/dist/{components → styles/matte}/Drawer.svelte +4 -7
  59. package/dist/{components → styles/matte}/Dropdown.svelte +18 -36
  60. package/dist/{components → styles/matte}/Dropdown.svelte.d.ts +1 -1
  61. package/dist/{components → styles/matte}/Dropzone.svelte +11 -43
  62. package/dist/{components → styles/matte}/Dropzone.svelte.d.ts +2 -5
  63. package/dist/{components → styles/matte}/EmptyState.svelte +1 -1
  64. package/dist/{components → styles/matte}/EmptyState.svelte.d.ts +1 -1
  65. package/dist/styles/matte/FeatureCard.svelte +58 -0
  66. package/dist/styles/matte/FeatureCard.svelte.d.ts +16 -0
  67. package/dist/styles/matte/FeatureGrid.svelte +62 -0
  68. package/dist/styles/matte/FeatureGrid.svelte.d.ts +16 -0
  69. package/dist/{components → styles/matte}/Footer.svelte +1 -1
  70. package/dist/{components → styles/matte}/Footer.svelte.d.ts +1 -1
  71. package/dist/styles/matte/HeroSection.svelte +80 -0
  72. package/dist/styles/matte/HeroSection.svelte.d.ts +21 -0
  73. package/dist/{components → styles/matte}/Input.svelte +1 -1
  74. package/dist/{components → styles/matte}/Input.svelte.d.ts +1 -1
  75. package/dist/{components → styles/matte}/Link.svelte +1 -1
  76. package/dist/{components → styles/matte}/Link.svelte.d.ts +1 -1
  77. package/dist/{components → styles/matte}/LocaleProvider.svelte +1 -1
  78. package/dist/{components → styles/matte}/LocaleProvider.svelte.d.ts +1 -1
  79. package/dist/styles/matte/LogoCloud.svelte +61 -0
  80. package/dist/styles/matte/LogoCloud.svelte.d.ts +19 -0
  81. package/dist/{components → styles/matte}/MenuItem.svelte +1 -1
  82. package/dist/{components → styles/matte}/MenuItem.svelte.d.ts +1 -1
  83. package/dist/{components → styles/matte}/Modal.svelte +4 -7
  84. package/dist/{components → styles/matte}/MultiSelect.svelte +18 -37
  85. package/dist/{components → styles/matte}/MultiSelect.svelte.d.ts +1 -1
  86. package/dist/{components → styles/matte}/Navbar.svelte +2 -2
  87. package/dist/{components → styles/matte}/Navbar.svelte.d.ts +1 -1
  88. package/dist/{components → styles/matte}/NumberInput.svelte +4 -8
  89. package/dist/{components → styles/matte}/NumberInput.svelte.d.ts +1 -1
  90. package/dist/{components → styles/matte}/Pagination.svelte +4 -15
  91. package/dist/{components → styles/matte}/Pagination.svelte.d.ts +1 -1
  92. package/dist/{components → styles/matte}/PasswordInput.svelte +4 -13
  93. package/dist/{components → styles/matte}/PasswordInput.svelte.d.ts +1 -1
  94. package/dist/{components → styles/matte}/Popover.svelte +16 -41
  95. package/dist/{components → styles/matte}/Popover.svelte.d.ts +1 -1
  96. package/dist/styles/matte/PricingCard.svelte +107 -0
  97. package/dist/styles/matte/PricingCard.svelte.d.ts +25 -0
  98. package/dist/{components → styles/matte}/Progress.svelte +3 -2
  99. package/dist/{components → styles/matte}/Progress.svelte.d.ts +1 -1
  100. package/dist/{components → styles/matte}/Radio.svelte +1 -1
  101. package/dist/{components → styles/matte}/Radio.svelte.d.ts +1 -1
  102. package/dist/{components → styles/matte}/RadioGroup.svelte +1 -1
  103. package/dist/{components → styles/matte}/RadioGroup.svelte.d.ts +1 -1
  104. package/dist/{components → styles/matte}/SegmentedControl.svelte +1 -1
  105. package/dist/{components → styles/matte}/SegmentedControl.svelte.d.ts +1 -1
  106. package/dist/{components → styles/matte}/Select.svelte +1 -1
  107. package/dist/{components → styles/matte}/Select.svelte.d.ts +1 -1
  108. package/dist/{components → styles/matte}/Sidebar.svelte +2 -2
  109. package/dist/{components → styles/matte}/Sidebar.svelte.d.ts +1 -1
  110. package/dist/{components → styles/matte}/Slider.svelte +3 -2
  111. package/dist/{components → styles/matte}/Slider.svelte.d.ts +1 -1
  112. package/dist/{components → styles/matte}/Spinner.svelte +2 -2
  113. package/dist/{components → styles/matte}/Spinner.svelte.d.ts +1 -1
  114. package/dist/{components → styles/matte}/Stat.svelte +1 -1
  115. package/dist/{components → styles/matte}/Stat.svelte.d.ts +1 -1
  116. package/dist/styles/matte/StatsBand.svelte +57 -0
  117. package/dist/styles/matte/StatsBand.svelte.d.ts +20 -0
  118. package/dist/{components → styles/matte}/Steps.svelte +1 -1
  119. package/dist/{components → styles/matte}/Steps.svelte.d.ts +1 -1
  120. package/dist/{components → styles/matte}/Switch.svelte +1 -1
  121. package/dist/{components → styles/matte}/Switch.svelte.d.ts +1 -1
  122. package/dist/{components → styles/matte}/Table.svelte +6 -28
  123. package/dist/{components → styles/matte}/Table.svelte.d.ts +2 -6
  124. package/dist/{components → styles/matte}/Tabs.svelte +8 -1
  125. package/dist/{components → styles/matte}/Tabs.svelte.d.ts +1 -1
  126. package/dist/styles/matte/Testimonial.svelte +67 -0
  127. package/dist/styles/matte/Testimonial.svelte.d.ts +19 -0
  128. package/dist/{components → styles/matte}/Textarea.svelte +1 -1
  129. package/dist/{components → styles/matte}/Textarea.svelte.d.ts +1 -1
  130. package/dist/{components → styles/matte}/ThemeToggle.svelte +14 -27
  131. package/dist/{components → styles/matte}/ThemeToggle.svelte.d.ts +2 -6
  132. package/dist/{components → styles/matte}/Toaster.svelte +4 -4
  133. package/dist/styles/matte/index.d.ts +109 -0
  134. package/dist/styles/matte/index.js +83 -0
  135. package/dist/styles/paper/Accordion.svelte +17 -0
  136. package/dist/styles/paper/Accordion.svelte.d.ts +8 -0
  137. package/dist/styles/paper/AccordionItem.svelte +46 -0
  138. package/dist/styles/paper/AccordionItem.svelte.d.ts +14 -0
  139. package/dist/styles/paper/Alert.svelte +99 -0
  140. package/dist/styles/paper/Alert.svelte.d.ts +18 -0
  141. package/dist/styles/paper/Avatar.svelte +60 -0
  142. package/dist/styles/paper/Avatar.svelte.d.ts +16 -0
  143. package/dist/styles/paper/AvatarGroup.svelte +17 -0
  144. package/dist/styles/paper/AvatarGroup.svelte.d.ts +8 -0
  145. package/dist/styles/paper/Badge.svelte +58 -0
  146. package/dist/styles/paper/Badge.svelte.d.ts +16 -0
  147. package/dist/styles/paper/Breadcrumb.svelte +49 -0
  148. package/dist/styles/paper/Breadcrumb.svelte.d.ts +14 -0
  149. package/dist/styles/paper/Button.svelte +96 -0
  150. package/dist/styles/paper/Button.svelte.d.ts +21 -0
  151. package/dist/styles/paper/CTASection.svelte +76 -0
  152. package/dist/styles/paper/CTASection.svelte.d.ts +18 -0
  153. package/dist/styles/paper/Calendar.svelte +202 -0
  154. package/dist/styles/paper/Calendar.svelte.d.ts +22 -0
  155. package/dist/styles/paper/Card.svelte +78 -0
  156. package/dist/styles/paper/Card.svelte.d.ts +21 -0
  157. package/dist/styles/paper/Checkbox.svelte +75 -0
  158. package/dist/styles/paper/Checkbox.svelte.d.ts +15 -0
  159. package/dist/styles/paper/CheckboxGroup.svelte +111 -0
  160. package/dist/styles/paper/CheckboxGroup.svelte.d.ts +30 -0
  161. package/dist/styles/paper/Combobox.svelte +266 -0
  162. package/dist/styles/paper/Combobox.svelte.d.ts +29 -0
  163. package/dist/styles/paper/CommandPalette.svelte +209 -0
  164. package/dist/styles/paper/CommandPalette.svelte.d.ts +32 -0
  165. package/dist/styles/paper/ConfirmDialog.svelte +97 -0
  166. package/dist/styles/paper/ConfirmDialog.svelte.d.ts +22 -0
  167. package/dist/styles/paper/ContextMenu.svelte +88 -0
  168. package/dist/styles/paper/ContextMenu.svelte.d.ts +15 -0
  169. package/dist/styles/paper/DatePicker.svelte +192 -0
  170. package/dist/styles/paper/DatePicker.svelte.d.ts +23 -0
  171. package/dist/styles/paper/Divider.svelte +30 -0
  172. package/dist/styles/paper/Divider.svelte.d.ts +10 -0
  173. package/dist/styles/paper/Drawer.svelte +165 -0
  174. package/dist/styles/paper/Drawer.svelte.d.ts +20 -0
  175. package/dist/styles/paper/Dropdown.svelte +94 -0
  176. package/dist/styles/paper/Dropdown.svelte.d.ts +23 -0
  177. package/dist/styles/paper/Dropzone.svelte +210 -0
  178. package/dist/styles/paper/Dropzone.svelte.d.ts +29 -0
  179. package/dist/styles/paper/EmptyState.svelte +71 -0
  180. package/dist/styles/paper/EmptyState.svelte.d.ts +18 -0
  181. package/dist/styles/paper/FeatureCard.svelte +58 -0
  182. package/dist/styles/paper/FeatureCard.svelte.d.ts +16 -0
  183. package/dist/styles/paper/FeatureGrid.svelte +62 -0
  184. package/dist/styles/paper/FeatureGrid.svelte.d.ts +16 -0
  185. package/dist/styles/paper/Field.svelte +42 -0
  186. package/dist/styles/paper/Field.svelte.d.ts +16 -0
  187. package/dist/styles/paper/Footer.svelte +91 -0
  188. package/dist/styles/paper/Footer.svelte.d.ts +25 -0
  189. package/dist/styles/paper/HeroSection.svelte +86 -0
  190. package/dist/styles/paper/HeroSection.svelte.d.ts +21 -0
  191. package/dist/styles/paper/Input.svelte +60 -0
  192. package/dist/styles/paper/Input.svelte.d.ts +18 -0
  193. package/dist/styles/paper/InputGroup.svelte +20 -0
  194. package/dist/styles/paper/InputGroup.svelte.d.ts +11 -0
  195. package/dist/styles/paper/Kbd.svelte +17 -0
  196. package/dist/styles/paper/Kbd.svelte.d.ts +8 -0
  197. package/dist/styles/paper/Label.svelte +16 -0
  198. package/dist/styles/paper/Label.svelte.d.ts +9 -0
  199. package/dist/styles/paper/Link.svelte +44 -0
  200. package/dist/styles/paper/Link.svelte.d.ts +16 -0
  201. package/dist/styles/paper/LocaleProvider.svelte +24 -0
  202. package/dist/styles/paper/LocaleProvider.svelte.d.ts +10 -0
  203. package/dist/styles/paper/LogoCloud.svelte +61 -0
  204. package/dist/styles/paper/LogoCloud.svelte.d.ts +19 -0
  205. package/dist/styles/paper/MenuItem.svelte +64 -0
  206. package/dist/styles/paper/MenuItem.svelte.d.ts +18 -0
  207. package/dist/styles/paper/MenuSeparator.svelte +22 -0
  208. package/dist/styles/paper/MenuSeparator.svelte.d.ts +8 -0
  209. package/dist/styles/paper/Modal.svelte +118 -0
  210. package/dist/styles/paper/Modal.svelte.d.ts +21 -0
  211. package/dist/styles/paper/MultiSelect.svelte +287 -0
  212. package/dist/styles/paper/MultiSelect.svelte.d.ts +31 -0
  213. package/dist/styles/paper/Navbar.svelte +201 -0
  214. package/dist/styles/paper/Navbar.svelte.d.ts +33 -0
  215. package/dist/styles/paper/NumberInput.svelte +96 -0
  216. package/dist/styles/paper/NumberInput.svelte.d.ts +15 -0
  217. package/dist/styles/paper/Pagination.svelte +83 -0
  218. package/dist/styles/paper/Pagination.svelte.d.ts +15 -0
  219. package/dist/styles/paper/PasswordInput.svelte +100 -0
  220. package/dist/styles/paper/PasswordInput.svelte.d.ts +12 -0
  221. package/dist/styles/paper/Popover.svelte +89 -0
  222. package/dist/styles/paper/Popover.svelte.d.ts +19 -0
  223. package/dist/styles/paper/PricingCard.svelte +108 -0
  224. package/dist/styles/paper/PricingCard.svelte.d.ts +25 -0
  225. package/dist/styles/paper/Progress.svelte +59 -0
  226. package/dist/styles/paper/Progress.svelte.d.ts +17 -0
  227. package/dist/styles/paper/Radio.svelte +55 -0
  228. package/dist/styles/paper/Radio.svelte.d.ts +15 -0
  229. package/dist/styles/paper/RadioGroup.svelte +95 -0
  230. package/dist/styles/paper/RadioGroup.svelte.d.ts +27 -0
  231. package/dist/styles/paper/SegmentedControl.svelte +88 -0
  232. package/dist/styles/paper/SegmentedControl.svelte.d.ts +25 -0
  233. package/dist/styles/paper/Select.svelte +61 -0
  234. package/dist/styles/paper/Select.svelte.d.ts +20 -0
  235. package/dist/styles/paper/Sidebar.svelte +206 -0
  236. package/dist/styles/paper/Sidebar.svelte.d.ts +36 -0
  237. package/dist/styles/paper/Skeleton.svelte +46 -0
  238. package/dist/styles/paper/Skeleton.svelte.d.ts +13 -0
  239. package/dist/styles/paper/Slider.svelte +80 -0
  240. package/dist/styles/paper/Slider.svelte.d.ts +19 -0
  241. package/dist/styles/paper/Spinner.svelte +34 -0
  242. package/dist/styles/paper/Spinner.svelte.d.ts +13 -0
  243. package/dist/styles/paper/Stat.svelte +51 -0
  244. package/dist/styles/paper/Stat.svelte.d.ts +16 -0
  245. package/dist/styles/paper/StatsBand.svelte +63 -0
  246. package/dist/styles/paper/StatsBand.svelte.d.ts +20 -0
  247. package/dist/styles/paper/Steps.svelte +141 -0
  248. package/dist/styles/paper/Steps.svelte.d.ts +24 -0
  249. package/dist/styles/paper/Switch.svelte +64 -0
  250. package/dist/styles/paper/Switch.svelte.d.ts +14 -0
  251. package/dist/styles/paper/Table.svelte +217 -0
  252. package/dist/styles/paper/Table.svelte.d.ts +66 -0
  253. package/dist/styles/paper/Tabs.svelte +102 -0
  254. package/dist/styles/paper/Tabs.svelte.d.ts +23 -0
  255. package/dist/styles/paper/Testimonial.svelte +64 -0
  256. package/dist/styles/paper/Testimonial.svelte.d.ts +19 -0
  257. package/dist/styles/paper/Textarea.svelte +54 -0
  258. package/dist/styles/paper/Textarea.svelte.d.ts +12 -0
  259. package/dist/styles/paper/ThemeToggle.svelte +130 -0
  260. package/dist/styles/paper/ThemeToggle.svelte.d.ts +16 -0
  261. package/dist/styles/paper/Toaster.svelte +132 -0
  262. package/dist/styles/paper/Toaster.svelte.d.ts +8 -0
  263. package/dist/styles/paper/Tooltip.svelte +33 -0
  264. package/dist/styles/paper/Tooltip.svelte.d.ts +12 -0
  265. package/dist/styles/paper/fonts.css +46 -0
  266. package/dist/styles/paper/index.d.ts +109 -0
  267. package/dist/styles/paper/index.js +83 -0
  268. package/dist/styles/paper/theme.css +222 -0
  269. package/package.json +531 -201
  270. package/registry.json +658 -339
  271. /package/dist/{actions → core/actions}/anchor.d.ts +0 -0
  272. /package/dist/{actions → core/actions}/anchor.js +0 -0
  273. /package/dist/{actions → core/actions}/dismissable.d.ts +0 -0
  274. /package/dist/{actions → core/actions}/dismissable.js +0 -0
  275. /package/dist/{date.d.ts → core/date.d.ts} +0 -0
  276. /package/dist/{date.js → core/date.js} +0 -0
  277. /package/dist/{locale.svelte.d.ts → core/locale.svelte.d.ts} +0 -0
  278. /package/dist/{locale.svelte.js → core/locale.svelte.js} +0 -0
  279. /package/dist/{toast.svelte.d.ts → core/toast.svelte.d.ts} +0 -0
  280. /package/dist/{toast.svelte.js → core/toast.svelte.js} +0 -0
  281. /package/dist/{tones.d.ts → core/tones.d.ts} +0 -0
  282. /package/dist/{tones.js → core/tones.js} +0 -0
  283. /package/dist/{components → styles/matte}/Accordion.svelte +0 -0
  284. /package/dist/{components → styles/matte}/Accordion.svelte.d.ts +0 -0
  285. /package/dist/{components → styles/matte}/AvatarGroup.svelte +0 -0
  286. /package/dist/{components → styles/matte}/AvatarGroup.svelte.d.ts +0 -0
  287. /package/dist/{components → styles/matte}/ContextMenu.svelte.d.ts +0 -0
  288. /package/dist/{components → styles/matte}/Divider.svelte +0 -0
  289. /package/dist/{components → styles/matte}/Divider.svelte.d.ts +0 -0
  290. /package/dist/{components → styles/matte}/Drawer.svelte.d.ts +0 -0
  291. /package/dist/{components → styles/matte}/Field.svelte +0 -0
  292. /package/dist/{components → styles/matte}/Field.svelte.d.ts +0 -0
  293. /package/dist/{components → styles/matte}/InputGroup.svelte +0 -0
  294. /package/dist/{components → styles/matte}/InputGroup.svelte.d.ts +0 -0
  295. /package/dist/{components → styles/matte}/Kbd.svelte +0 -0
  296. /package/dist/{components → styles/matte}/Kbd.svelte.d.ts +0 -0
  297. /package/dist/{components → styles/matte}/Label.svelte +0 -0
  298. /package/dist/{components → styles/matte}/Label.svelte.d.ts +0 -0
  299. /package/dist/{components → styles/matte}/MenuSeparator.svelte +0 -0
  300. /package/dist/{components → styles/matte}/MenuSeparator.svelte.d.ts +0 -0
  301. /package/dist/{components → styles/matte}/Modal.svelte.d.ts +0 -0
  302. /package/dist/{components → styles/matte}/Skeleton.svelte +0 -0
  303. /package/dist/{components → styles/matte}/Skeleton.svelte.d.ts +0 -0
  304. /package/dist/{components → styles/matte}/Toaster.svelte.d.ts +0 -0
  305. /package/dist/{components → styles/matte}/Tooltip.svelte +0 -0
  306. /package/dist/{components → styles/matte}/Tooltip.svelte.d.ts +0 -0
  307. /package/dist/{fonts.css → styles/matte/fonts.css} +0 -0
  308. /package/dist/{theme.css → styles/matte/theme.css} +0 -0
@@ -0,0 +1,80 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { toneText, type Tone } from '../../core/tones.js';
5
+
6
+ interface Props extends HTMLAttributes<HTMLElement> {
7
+ /** Small line above the headline. */
8
+ eyebrow?: string;
9
+ title: string;
10
+ description?: string;
11
+ tone?: Tone;
12
+ /** `center` also centres the actions. Ignored when `media` is set. */
13
+ align?: 'left' | 'center';
14
+ /** Buttons under the copy. */
15
+ actions?: Snippet;
16
+ /** Anything on the right — a screenshot, an illustration, a form. */
17
+ media?: Snippet;
18
+ /** Extra content between the description and the actions. */
19
+ children?: Snippet;
20
+ }
21
+
22
+ let {
23
+ eyebrow,
24
+ title,
25
+ description,
26
+ tone = 'brand',
27
+ align = 'left',
28
+ actions,
29
+ media,
30
+ class: className = '',
31
+ children,
32
+ ...rest
33
+ }: Props = $props();
34
+
35
+ // A media column only makes sense next to left-aligned copy.
36
+ const centred = $derived(align === 'center' && !media);
37
+ </script>
38
+
39
+ <section class="w-full px-6 py-20 sm:py-28 {className}" {...rest}>
40
+ <div
41
+ class="mx-auto flex w-full max-w-6xl gap-16
42
+ {media ? 'flex-col lg:flex-row lg:items-center' : 'flex-col'}"
43
+ >
44
+ <div
45
+ class="flex min-w-0 flex-1 flex-col gap-6 {centred
46
+ ? 'items-center text-center'
47
+ : 'items-start'}"
48
+ >
49
+ {#if eyebrow}
50
+ <span class="font-mono text-xs tracking-wide uppercase {toneText[tone]}">{eyebrow}</span>
51
+ {/if}
52
+
53
+ <h1
54
+ class="max-w-2xl font-heading text-4xl leading-tight font-medium tracking-tight text-balance text-text sm:text-5xl"
55
+ >
56
+ {title}
57
+ </h1>
58
+
59
+ {#if description}
60
+ <p class="max-w-xl font-sans text-lg leading-relaxed text-pretty text-text-secondary">
61
+ {description}
62
+ </p>
63
+ {/if}
64
+
65
+ {#if children}
66
+ {@render children()}
67
+ {/if}
68
+
69
+ {#if actions}
70
+ <div class="flex flex-wrap items-center gap-3 pt-2 {centred ? 'justify-center' : ''}">
71
+ {@render actions()}
72
+ </div>
73
+ {/if}
74
+ </div>
75
+
76
+ {#if media}
77
+ <div class="min-w-0 flex-1">{@render media()}</div>
78
+ {/if}
79
+ </div>
80
+ </section>
@@ -0,0 +1,21 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { type Tone } from '../../core/tones.js';
4
+ interface Props extends HTMLAttributes<HTMLElement> {
5
+ /** Small line above the headline. */
6
+ eyebrow?: string;
7
+ title: string;
8
+ description?: string;
9
+ tone?: Tone;
10
+ /** `center` also centres the actions. Ignored when `media` is set. */
11
+ align?: 'left' | 'center';
12
+ /** Buttons under the copy. */
13
+ actions?: Snippet;
14
+ /** Anything on the right — a screenshot, an illustration, a form. */
15
+ media?: Snippet;
16
+ /** Extra content between the description and the actions. */
17
+ children?: Snippet;
18
+ }
19
+ declare const HeroSection: import("svelte").Component<Props, {}, "">;
20
+ type HeroSection = ReturnType<typeof HeroSection>;
21
+ export default HeroSection;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLInputAttributes } from 'svelte/elements';
4
- import { toneFocusWithinBorder, type Tone } from '../tones.js';
4
+ import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
5
5
 
6
6
  export type InputSize = 'sm' | 'md' | 'lg';
7
7
 
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  export type InputSize = 'sm' | 'md' | 'lg';
5
5
  interface Props extends Omit<HTMLInputAttributes, 'size' | 'prefix' | 'suffix'> {
6
6
  value?: string;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAnchorAttributes } from 'svelte/elements';
4
- import { focusRing, toneHoverText, toneRing, toneText, type Tone } from '../tones.js';
4
+ import { focusRing, toneHoverText, toneRing, toneText, type Tone } from '../../core/tones.js';
5
5
 
6
6
  interface Props extends HTMLAnchorAttributes {
7
7
  tone?: Tone;
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAnchorAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  interface Props extends HTMLAnchorAttributes {
5
5
  tone?: Tone;
6
6
  /** `'hover'` shows the rule only on hover. */
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import { provideLocale, type Locale } from '../locale.svelte.js';
3
+ import { provideLocale, type Locale } from '../../core/locale.svelte.js';
4
4
 
5
5
  interface Props {
6
6
  /** Full locale or just the keys you want to change. */
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import { type Locale } from '../locale.svelte.js';
2
+ import { type Locale } from '../../core/locale.svelte.js';
3
3
  interface Props {
4
4
  /** Full locale or just the keys you want to change. */
5
5
  locale: Partial<Locale>;
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+
5
+ export interface Logo {
6
+ name: string;
7
+ src?: string;
8
+ href?: string;
9
+ }
10
+
11
+ interface Props extends HTMLAttributes<HTMLElement> {
12
+ title?: string;
13
+ /** Without `src` the name is set in the heading face — fine for wordmarks. */
14
+ logos?: Logo[];
15
+ /** Dim until hovered, so the row does not compete with the headline. */
16
+ muted?: boolean;
17
+ /** Your own markup instead of `logos`. */
18
+ children?: Snippet;
19
+ }
20
+
21
+ let {
22
+ title,
23
+ logos = [],
24
+ muted = true,
25
+ class: className = '',
26
+ children,
27
+ ...rest
28
+ }: Props = $props();
29
+ </script>
30
+
31
+ <section class="w-full px-6 py-14 {className}" {...rest}>
32
+ <div class="mx-auto flex w-full max-w-6xl flex-col items-center gap-8">
33
+ {#if title}
34
+ <p class="text-center font-mono text-xs tracking-wide text-text-muted uppercase">{title}</p>
35
+ {/if}
36
+
37
+ <div class="flex flex-wrap items-center justify-center gap-x-12 gap-y-8">
38
+ {#if children}
39
+ {@render children()}
40
+ {:else}
41
+ {#each logos as logo (logo.name)}
42
+ <svelte:element
43
+ this={logo.href ? 'a' : 'div'}
44
+ href={logo.href}
45
+ class="flex items-center transition-all duration-200 ease-brand-out {muted
46
+ ? 'opacity-60 grayscale hover:opacity-100 hover:grayscale-0'
47
+ : ''}"
48
+ >
49
+ {#if logo.src}
50
+ <img src={logo.src} alt={logo.name} class="h-7 w-auto object-contain" />
51
+ {:else}
52
+ <span class="font-heading text-lg font-medium tracking-tight text-text-secondary">
53
+ {logo.name}
54
+ </span>
55
+ {/if}
56
+ </svelte:element>
57
+ {/each}
58
+ {/if}
59
+ </div>
60
+ </div>
61
+ </section>
@@ -0,0 +1,19 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ export interface Logo {
4
+ name: string;
5
+ src?: string;
6
+ href?: string;
7
+ }
8
+ interface Props extends HTMLAttributes<HTMLElement> {
9
+ title?: string;
10
+ /** Without `src` the name is set in the heading face — fine for wordmarks. */
11
+ logos?: Logo[];
12
+ /** Dim until hovered, so the row does not compete with the headline. */
13
+ muted?: boolean;
14
+ /** Your own markup instead of `logos`. */
15
+ children?: Snippet;
16
+ }
17
+ declare const LogoCloud: import("svelte").Component<Props, {}, "">;
18
+ type LogoCloud = ReturnType<typeof LogoCloud>;
19
+ export default LogoCloud;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLButtonAttributes } from 'svelte/elements';
4
- import { toneSoftHover, toneText, type Tone } from '../tones.js';
4
+ import { toneSoftHover, toneText, type Tone } from '../../core/tones.js';
5
5
 
6
6
  interface Props extends HTMLButtonAttributes {
7
7
  /** Renders an `<a>` instead of a `<button>`. */
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLButtonAttributes } from 'svelte/elements';
3
- import { type Tone } from '../tones.js';
3
+ import { type Tone } from '../../core/tones.js';
4
4
  interface Props extends HTMLButtonAttributes {
5
5
  /** Renders an `<a>` instead of a `<button>`. */
6
6
  href?: string;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLDialogAttributes } from 'svelte/elements';
4
- import { useLocale } from '../locale.svelte.js';
4
+ import { useLocale } from '../../core/locale.svelte.js';
5
+ import { isBackdropClick, syncDialog } from '../../core/dialog.svelte.js';
5
6
 
6
7
  export type ModalSize = 'sm' | 'md' | 'lg';
7
8
 
@@ -46,11 +47,7 @@
46
47
  lg: 'max-w-2xl'
47
48
  };
48
49
 
49
- $effect(() => {
50
- if (!dialog) return;
51
- if (open && !dialog.open) dialog.showModal();
52
- else if (!open && dialog.open) dialog.close();
53
- });
50
+ $effect(() => syncDialog(dialog, open));
54
51
 
55
52
  function close() {
56
53
  open = false;
@@ -59,7 +56,7 @@
59
56
 
60
57
  function onBackdrop(event: MouseEvent) {
61
58
  if (!dismissible) return;
62
- if (event.target === dialog) close();
59
+ if (isBackdropClick(event, dialog)) close();
63
60
  }
64
61
  </script>
65
62
 
@@ -9,10 +9,11 @@
9
9
  </script>
10
10
 
11
11
  <script lang="ts">
12
- import { anchored } from '../actions/anchor.js';
13
- import { clickOutside, portal } from '../actions/dismissable.js';
14
- import { useLocale } from '../locale.svelte.js';
15
- import { toneFocusWithinBorder, toneSoft, toneText, type Tone } from '../tones.js';
12
+ import { anchored } from '../../core/actions/anchor.js';
13
+ import { clickOutside, portal } from '../../core/actions/dismissable.js';
14
+ import { ListCursor, groupItems, matchQuery, revealIndex } from '../../core/list.svelte.js';
15
+ import { useLocale } from '../../core/locale.svelte.js';
16
+ import { toneFocusWithinBorder, toneSoft, toneText, type Tone } from '../../core/tones.js';
16
17
 
17
18
  interface Props {
18
19
  /** Bindable — the `value` of every chosen option. */
@@ -56,7 +57,6 @@
56
57
 
57
58
  let open = $state(false);
58
59
  let query = $state('');
59
- let active = $state(0);
60
60
  let wrapper: HTMLElement | null = $state(null);
61
61
  let inputEl: HTMLInputElement | null = $state(null);
62
62
  let listEl: HTMLElement | null = $state(null);
@@ -67,29 +67,16 @@
67
67
  const full = $derived(max > 0 && value.length >= max);
68
68
  const collapsed = $derived(maxChips > 0 && chosen.length > maxChips);
69
69
 
70
- const matches = $derived.by(() => {
71
- const needle = query.trim().toLowerCase();
72
- if (!needle) return options;
73
- return options.filter(
74
- (option) =>
75
- option.label.toLowerCase().includes(needle) ||
76
- option.description?.toLowerCase().includes(needle)
77
- );
78
- });
79
-
80
- const groups = $derived.by(() => {
81
- const out: [string, MultiSelectOption[]][] = [];
82
- for (const option of matches) {
83
- const key = option.group ?? '';
84
- const bucket = out.find(([n]) => n === key);
85
- if (bucket) bucket[1].push(option);
86
- else out.push([key, [option]]);
87
- }
88
- return out;
89
- });
70
+ const matches = $derived(
71
+ matchQuery(options, query, (option) => `${option.label} ${option.description ?? ''}`)
72
+ );
90
73
 
74
+ const groups = $derived(groupItems(matches));
91
75
  const flat = $derived(groups.flatMap(([, items]) => items));
92
76
 
77
+ const cursor = new ListCursor(() => flat);
78
+ const active = $derived(cursor.index);
79
+
93
80
  function toggle(option: MultiSelectOption) {
94
81
  const has = value.includes(option.value);
95
82
  if (option.disabled || (!has && full)) return;
@@ -103,14 +90,8 @@
103
90
  }
104
91
 
105
92
  function move(step: number) {
106
- if (flat.length === 0) return;
107
- let next = active;
108
- for (let i = 0; i < flat.length; i++) {
109
- next = (next + step + flat.length) % flat.length;
110
- if (!flat[next].disabled) break;
111
- }
112
- active = next;
113
- listEl?.querySelector(`[data-index="${next}"]`)?.scrollIntoView({ block: 'nearest' });
93
+ cursor.move(step);
94
+ revealIndex(listEl, cursor.index);
114
95
  }
115
96
 
116
97
  function onKeydown(event: KeyboardEvent) {
@@ -125,9 +106,9 @@
125
106
  if (open) move(-1);
126
107
  break;
127
108
  case 'Enter':
128
- if (open && flat[active]) {
109
+ if (open && cursor.current) {
129
110
  event.preventDefault();
130
- toggle(flat[active]);
111
+ toggle(cursor.current);
131
112
  }
132
113
  break;
133
114
  case 'Backspace':
@@ -201,7 +182,7 @@
201
182
  placeholder={chosen.length ? '' : (placeholder ?? t.current.comboboxPlaceholder)}
202
183
  oninput={() => {
203
184
  open = true;
204
- active = 0;
185
+ cursor.index = 0;
205
186
  }}
206
187
  onfocus={() => (open = true)}
207
188
  onkeydown={onKeydown}
@@ -263,7 +244,7 @@
263
244
  aria-selected={checked}
264
245
  aria-disabled={option.disabled || (full && !checked)}
265
246
  onclick={() => toggle(option)}
266
- onpointermove={() => (active = index)}
247
+ onpointermove={() => (cursor.index = index)}
267
248
  class="flex cursor-pointer items-start gap-2.5 px-3 py-2 text-[14px] transition-colors duration-100
268
249
  {option.disabled || (full && !checked) ? 'pointer-events-none opacity-40' : ''}
269
250
  {index === active ? toneSoft[tone] : 'text-text-secondary'}"
@@ -5,7 +5,7 @@ export interface MultiSelectOption {
5
5
  disabled?: boolean;
6
6
  group?: string;
7
7
  }
8
- import { type Tone } from '../tones.js';
8
+ import { type Tone } from '../../core/tones.js';
9
9
  interface Props {
10
10
  /** Bindable — the `value` of every chosen option. */
11
11
  value?: string[];
@@ -14,8 +14,8 @@
14
14
 
15
15
  <script lang="ts">
16
16
  import type { Snippet } from 'svelte';
17
- import { useLocale } from '../locale.svelte.js';
18
- import { focusRing, toneRing, toneText, type Tone } from '../tones.js';
17
+ import { useLocale } from '../../core/locale.svelte.js';
18
+ import { focusRing, toneRing, toneText, type Tone } from '../../core/tones.js';
19
19
  import Drawer from './Drawer.svelte';
20
20
  import Dropdown from './Dropdown.svelte';
21
21
  import MenuItem from './MenuItem.svelte';
@@ -10,7 +10,7 @@ export interface NavItem {
10
10
  badge?: string | number;
11
11
  }
12
12
  import type { Snippet } from 'svelte';
13
- import { type Tone } from '../tones.js';
13
+ import { type Tone } from '../../core/tones.js';
14
14
  interface Props {
15
15
  items?: NavItem[];
16
16
  /** Logo or wordmark on the left. */
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { toneFocusWithinBorder, type Tone } from '../tones.js';
4
- import { useLocale } from '../locale.svelte.js';
3
+ import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
4
+ import { useLocale } from '../../core/locale.svelte.js';
5
+ import { clampToStep } from '../../core/number.js';
5
6
 
6
7
  interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
7
8
  value?: number;
@@ -29,12 +30,7 @@
29
30
 
30
31
  const t = useLocale();
31
32
 
32
- const decimals = $derived((String(step).split('.')[1] ?? '').length);
33
-
34
- function clamp(next: number) {
35
- if (Number.isNaN(next)) return min === -Infinity ? 0 : min;
36
- return Number(Math.min(max, Math.max(min, next)).toFixed(decimals));
37
- }
33
+ const clamp = (next: number) => clampToStep(next, min, max, step);
38
34
 
39
35
  function nudge(direction: 1 | -1) {
40
36
  value = clamp(value + direction * step);
@@ -1,5 +1,5 @@
1
1
  import type { HTMLInputAttributes } from 'svelte/elements';
2
- import { type Tone } from '../tones.js';
2
+ import { type Tone } from '../../core/tones.js';
3
3
  interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
4
4
  value?: number;
5
5
  min?: number;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { focusRing, toneRing, toneSolid, type Tone } from '../tones.js';
4
- import { useLocale } from '../locale.svelte.js';
3
+ import { focusRing, toneRing, toneSolid, type Tone } from '../../core/tones.js';
4
+ import { useLocale } from '../../core/locale.svelte.js';
5
+ import { pageRange } from '../../core/pagination.js';
5
6
 
6
7
  interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onchange'> {
7
8
  /** Bindable, 1-based. */
@@ -26,19 +27,7 @@
26
27
 
27
28
  const t = useLocale();
28
29
 
29
- const pages = $derived.by<(number | '…')[]>(() => {
30
- if (total <= 5 + siblings * 2) {
31
- return Array.from({ length: total }, (_, i) => i + 1);
32
- }
33
- const start = Math.max(2, page - siblings);
34
- const end = Math.min(total - 1, page + siblings);
35
- const out: (number | '…')[] = [1];
36
- if (start > 2) out.push('…');
37
- for (let i = start; i <= end; i++) out.push(i);
38
- if (end < total - 1) out.push('…');
39
- out.push(total);
40
- return out;
41
- });
30
+ const pages = $derived(pageRange(page, total, siblings));
42
31
 
43
32
  function go(next: number) {
44
33
  const clamped = Math.min(total, Math.max(1, next));
@@ -1,5 +1,5 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
- import { type Tone } from '../tones.js';
2
+ import { type Tone } from '../../core/tones.js';
3
3
  interface Props extends Omit<HTMLAttributes<HTMLElement>, 'onchange'> {
4
4
  /** Bindable, 1-based. */
5
5
  page?: number;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { toneFocusWithinBorder, type Tone } from '../tones.js';
4
- import { useLocale } from '../locale.svelte.js';
3
+ import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
4
+ import { useLocale } from '../../core/locale.svelte.js';
5
+ import { passwordScore } from '../../core/password.js';
5
6
 
6
7
  interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
7
8
  value?: string;
@@ -25,17 +26,7 @@
25
26
 
26
27
  let visible = $state(false);
27
28
 
28
- /** Deliberately simple: length plus character variety, four buckets. */
29
- const score = $derived.by(() => {
30
- if (!value) return 0;
31
- let points = 0;
32
- if (value.length >= 8) points++;
33
- if (value.length >= 12) points++;
34
- if (/[a-z]/.test(value) && /[A-Z]/.test(value)) points++;
35
- if (/\d/.test(value)) points++;
36
- if (/[^\w\s]/.test(value)) points++;
37
- return Math.min(4, points);
38
- });
29
+ const score = $derived(passwordScore(value));
39
30
 
40
31
  const bars = ['bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success'];
41
32
  const texts = ['text-danger', 'text-danger', 'text-warning', 'text-info', 'text-success'];
@@ -1,5 +1,5 @@
1
1
  import type { HTMLInputAttributes } from 'svelte/elements';
2
- import { type Tone } from '../tones.js';
2
+ import { type Tone } from '../../core/tones.js';
3
3
  interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
4
4
  value?: string;
5
5
  tone?: Tone;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import { anchored, type Placement } from '../actions/anchor.js';
4
- import { clickOutside, focusTrap, portal } from '../actions/dismissable.js';
3
+ import { anchored, type Placement } from '../../core/actions/anchor.js';
4
+ import { clickOutside, focusTrap, portal } from '../../core/actions/dismissable.js';
5
+ import { HOVER_GRACE, describeTrigger, popupTrigger } from '../../core/trigger.js';
5
6
 
6
7
  interface Props {
7
8
  trigger: Snippet;
@@ -32,45 +33,10 @@
32
33
  }: Props = $props();
33
34
 
34
35
  let anchorEl: HTMLElement | null = $state(null);
36
+ /** Held so the panel itself can cancel the hover close it inherited. */
35
37
  let closeTimer: ReturnType<typeof setTimeout> | undefined;
36
38
 
37
- function triggerBehaviour(node: HTMLElement) {
38
- const toggle = () => (open = !open);
39
- const show = () => {
40
- clearTimeout(closeTimer);
41
- open = true;
42
- };
43
- const hide = () => {
44
- closeTimer = setTimeout(() => (open = false), 120);
45
- };
46
-
47
- if (on === 'click') {
48
- node.addEventListener('click', toggle);
49
- } else {
50
- node.addEventListener('pointerenter', show);
51
- node.addEventListener('pointerleave', hide);
52
- node.addEventListener('focusin', show);
53
- node.addEventListener('focusout', hide);
54
- }
55
-
56
- return {
57
- destroy() {
58
- clearTimeout(closeTimer);
59
- node.removeEventListener('click', toggle);
60
- node.removeEventListener('pointerenter', show);
61
- node.removeEventListener('pointerleave', hide);
62
- node.removeEventListener('focusin', show);
63
- node.removeEventListener('focusout', hide);
64
- }
65
- };
66
- }
67
-
68
- $effect(() => {
69
- const control = anchorEl?.querySelector('button, a, [role="button"]');
70
- if (!control) return;
71
- control.setAttribute('aria-haspopup', 'dialog');
72
- control.setAttribute('aria-expanded', String(open));
73
- });
39
+ $effect(() => describeTrigger(anchorEl, 'dialog', open));
74
40
 
75
41
  function onKeydown(event: KeyboardEvent) {
76
42
  if (event.key !== 'Escape') return;
@@ -80,7 +46,16 @@
80
46
  }
81
47
  </script>
82
48
 
83
- <span bind:this={anchorEl} use:triggerBehaviour class="inline-flex {triggerClass}">
49
+ <span
50
+ bind:this={anchorEl}
51
+ use:popupTrigger={{
52
+ toggle: () => (open = !open),
53
+ open: () => (open = true),
54
+ close: () => (open = false),
55
+ on
56
+ }}
57
+ class="inline-flex {triggerClass}"
58
+ >
84
59
  {@render trigger()}
85
60
  </span>
86
61
 
@@ -97,7 +72,7 @@
97
72
  onkeydown={onKeydown}
98
73
  onpointerenter={() => clearTimeout(closeTimer)}
99
74
  onpointerleave={() => {
100
- if (on === 'hover') closeTimer = setTimeout(() => (open = false), 120);
75
+ if (on === 'hover') closeTimer = setTimeout(() => (open = false), HOVER_GRACE);
101
76
  }}
102
77
  role="dialog"
103
78
  aria-label={title}
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import { type Placement } from '../actions/anchor.js';
2
+ import { type Placement } from '../../core/actions/anchor.js';
3
3
  interface Props {
4
4
  trigger: Snippet;
5
5
  children: Snippet;