@dtsports/design-system 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/dist/components/accordion.d.ts +19 -0
  4. package/dist/components/accordion.d.ts.map +1 -0
  5. package/dist/components/accordion.js +26 -0
  6. package/dist/components/accordion.js.map +1 -0
  7. package/dist/components/alert.d.ts +26 -0
  8. package/dist/components/alert.d.ts.map +1 -0
  9. package/dist/components/alert.js.map +1 -0
  10. package/dist/components/app-shell.d.ts +21 -0
  11. package/dist/components/app-shell.d.ts.map +1 -0
  12. package/dist/components/app-shell.js +25 -0
  13. package/dist/components/app-shell.js.map +1 -0
  14. package/dist/components/aspect-ratio.d.ts +16 -0
  15. package/dist/components/aspect-ratio.d.ts.map +1 -0
  16. package/dist/components/aspect-ratio.js +17 -0
  17. package/dist/components/aspect-ratio.js.map +1 -0
  18. package/dist/components/avatar-group.d.ts +31 -0
  19. package/dist/components/avatar-group.d.ts.map +1 -0
  20. package/dist/components/avatar.d.ts +15 -0
  21. package/dist/components/avatar.d.ts.map +1 -0
  22. package/dist/components/avatar.js +20 -0
  23. package/dist/components/avatar.js.map +1 -0
  24. package/dist/components/badge.d.ts +27 -0
  25. package/dist/components/badge.d.ts.map +1 -0
  26. package/dist/components/badge.js +51 -0
  27. package/dist/components/badge.js.map +1 -0
  28. package/dist/components/breadcrumb.js.map +1 -0
  29. package/dist/components/button.d.ts +33 -0
  30. package/dist/components/button.d.ts.map +1 -0
  31. package/dist/components/button.js +58 -0
  32. package/dist/components/button.js.map +1 -0
  33. package/dist/components/calendar.d.ts +15 -0
  34. package/dist/components/calendar.d.ts.map +1 -0
  35. package/dist/components/calendar.js +33 -0
  36. package/dist/components/calendar.js.map +1 -0
  37. package/dist/components/capacity-bar.d.ts +32 -0
  38. package/dist/components/capacity-bar.d.ts.map +1 -0
  39. package/dist/components/capacity-bar.js +29 -0
  40. package/dist/components/capacity-bar.js.map +1 -0
  41. package/dist/components/card.d.ts +26 -0
  42. package/dist/components/card.d.ts.map +1 -0
  43. package/dist/components/card.js +20 -0
  44. package/dist/components/checkbox.d.ts +11 -0
  45. package/dist/components/checkbox.d.ts.map +1 -0
  46. package/dist/components/checkbox.js +19 -0
  47. package/dist/components/chip.d.ts +23 -0
  48. package/dist/components/chip.d.ts.map +1 -0
  49. package/dist/components/chip.js +32 -0
  50. package/dist/components/chip.js.map +1 -0
  51. package/dist/components/collapsible.d.ts +16 -0
  52. package/dist/components/collapsible.js +22 -0
  53. package/dist/components/collapsible.js.map +1 -0
  54. package/dist/components/combobox.d.ts +38 -0
  55. package/dist/components/combobox.d.ts.map +1 -0
  56. package/dist/components/combobox.js +17 -0
  57. package/dist/components/combobox.js.map +1 -0
  58. package/dist/components/confirm-action.d.ts +36 -0
  59. package/dist/components/confirm-action.d.ts.map +1 -0
  60. package/dist/components/confirm-action.js +21 -0
  61. package/dist/components/confirm-action.js.map +1 -0
  62. package/dist/components/container.js.map +1 -0
  63. package/dist/components/date-picker.d.ts.map +1 -0
  64. package/dist/components/date-picker.js +22 -0
  65. package/dist/components/date-picker.js.map +1 -0
  66. package/dist/components/dialog.d.ts +28 -0
  67. package/dist/components/dialog.d.ts.map +1 -0
  68. package/dist/components/dialog.js.map +1 -0
  69. package/dist/components/drawer.js +55 -0
  70. package/dist/components/drawer.js.map +1 -0
  71. package/dist/components/dropdown-menu.d.ts +39 -0
  72. package/dist/components/dropdown-menu.d.ts.map +1 -0
  73. package/dist/components/dropdown-menu.js +47 -0
  74. package/dist/components/empty-state.d.ts +15 -0
  75. package/dist/components/empty-state.d.ts.map +1 -0
  76. package/dist/components/empty-state.js +6 -0
  77. package/dist/components/form-field.d.ts +32 -0
  78. package/dist/components/form-field.d.ts.map +1 -0
  79. package/dist/components/form-field.js +31 -0
  80. package/dist/components/form-field.js.map +1 -0
  81. package/dist/components/input.d.ts +10 -0
  82. package/dist/components/input.d.ts.map +1 -0
  83. package/dist/components/input.js +6 -0
  84. package/dist/components/input.js.map +1 -0
  85. package/dist/components/label.d.ts +11 -0
  86. package/dist/components/label.d.ts.map +1 -0
  87. package/dist/components/label.js +13 -0
  88. package/dist/components/label.js.map +1 -0
  89. package/dist/components/live-pill.d.ts +14 -0
  90. package/dist/components/live-pill.js +15 -0
  91. package/dist/components/live-pill.js.map +1 -0
  92. package/dist/components/metric-tile.d.ts +23 -0
  93. package/dist/components/metric-tile.d.ts.map +1 -0
  94. package/dist/components/money-breakdown.d.ts +36 -0
  95. package/dist/components/money-breakdown.d.ts.map +1 -0
  96. package/dist/components/money-breakdown.js +12 -0
  97. package/dist/components/money-breakdown.js.map +1 -0
  98. package/dist/components/number-input.d.ts +16 -0
  99. package/dist/components/number-input.d.ts.map +1 -0
  100. package/dist/components/number-input.js +30 -0
  101. package/dist/components/number-input.js.map +1 -0
  102. package/dist/components/pagination.d.ts +27 -0
  103. package/dist/components/pagination.d.ts.map +1 -0
  104. package/dist/components/pagination.js +52 -0
  105. package/dist/components/pagination.js.map +1 -0
  106. package/dist/components/popover.d.ts +24 -0
  107. package/dist/components/popover.d.ts.map +1 -0
  108. package/dist/components/popover.js +28 -0
  109. package/dist/components/popover.js.map +1 -0
  110. package/dist/components/progress.d.ts +13 -0
  111. package/dist/components/progress.d.ts.map +1 -0
  112. package/dist/components/progress.js +17 -0
  113. package/dist/components/radio-group.d.ts +10 -0
  114. package/dist/components/radio-group.d.ts.map +1 -0
  115. package/dist/components/radio-group.js +17 -0
  116. package/dist/components/radio-group.js.map +1 -0
  117. package/dist/components/scroll-area.d.ts.map +1 -0
  118. package/dist/components/scroll-area.js +22 -0
  119. package/dist/components/scroll-area.js.map +1 -0
  120. package/dist/components/select.d.ts +27 -0
  121. package/dist/components/select.d.ts.map +1 -0
  122. package/dist/components/select.js +40 -0
  123. package/dist/components/select.js.map +1 -0
  124. package/dist/components/separator.d.ts +10 -0
  125. package/dist/components/separator.d.ts.map +1 -0
  126. package/dist/components/separator.js +14 -0
  127. package/dist/components/separator.js.map +1 -0
  128. package/dist/components/sidebar.d.ts.map +1 -0
  129. package/dist/components/sidebar.js +48 -0
  130. package/dist/components/sidebar.js.map +1 -0
  131. package/dist/components/skeleton.d.ts +23 -0
  132. package/dist/components/skeleton.js +25 -0
  133. package/dist/components/skeleton.js.map +1 -0
  134. package/dist/components/slider.d.ts +14 -0
  135. package/dist/components/slider.d.ts.map +1 -0
  136. package/dist/components/slider.js +30 -0
  137. package/dist/components/slider.js.map +1 -0
  138. package/dist/components/spec.d.ts +35 -0
  139. package/dist/components/spec.js +31 -0
  140. package/dist/components/spec.js.map +1 -0
  141. package/dist/components/spinner.d.ts +20 -0
  142. package/dist/components/spinner.d.ts.map +1 -0
  143. package/dist/components/spinner.js +18 -0
  144. package/dist/components/spinner.js.map +1 -0
  145. package/dist/components/stack.d.ts +48 -0
  146. package/dist/components/stack.d.ts.map +1 -0
  147. package/dist/components/stack.js +43 -0
  148. package/dist/components/stack.js.map +1 -0
  149. package/dist/components/status-pill.js +34 -0
  150. package/dist/components/status-pill.js.map +1 -0
  151. package/dist/components/switch.d.ts +9 -0
  152. package/dist/components/switch.d.ts.map +1 -0
  153. package/dist/components/switch.js +15 -0
  154. package/dist/components/switch.js.map +1 -0
  155. package/dist/components/table.d.ts +31 -0
  156. package/dist/components/table.d.ts.map +1 -0
  157. package/dist/components/tabs.d.ts +22 -0
  158. package/dist/components/tabs.d.ts.map +1 -0
  159. package/dist/components/tabs.js +28 -0
  160. package/dist/components/tabs.js.map +1 -0
  161. package/dist/components/textarea.d.ts +8 -0
  162. package/dist/components/textarea.d.ts.map +1 -0
  163. package/dist/components/textarea.js +6 -0
  164. package/dist/components/textarea.js.map +1 -0
  165. package/dist/components/theme-provider.d.ts +35 -0
  166. package/dist/components/theme-provider.d.ts.map +1 -0
  167. package/dist/components/theme-provider.js.map +1 -0
  168. package/dist/components/theme-toggle.d.ts +10 -0
  169. package/dist/components/theme-toggle.d.ts.map +1 -0
  170. package/dist/components/theme-toggle.js.map +1 -0
  171. package/dist/components/three-state.d.ts +39 -0
  172. package/dist/components/three-state.d.ts.map +1 -0
  173. package/dist/components/three-state.js +24 -0
  174. package/dist/components/three-state.js.map +1 -0
  175. package/dist/components/timestamp.d.ts +24 -0
  176. package/dist/components/timestamp.js +64 -0
  177. package/dist/components/timestamp.js.map +1 -0
  178. package/dist/components/toaster.d.ts +27 -0
  179. package/dist/components/toaster.d.ts.map +1 -0
  180. package/dist/components/toaster.js +21 -0
  181. package/dist/components/toaster.js.map +1 -0
  182. package/dist/components/tooltip.d.ts +28 -0
  183. package/dist/components/tooltip.d.ts.map +1 -0
  184. package/dist/components/tooltip.js.map +1 -0
  185. package/dist/components/top-bar.d.ts +13 -0
  186. package/dist/components/top-bar.d.ts.map +1 -0
  187. package/dist/components/top-bar.js +16 -0
  188. package/dist/index.d.ts +76 -0
  189. package/dist/index.d.ts.map +1 -0
  190. package/dist/index.js +86 -0
  191. package/dist/index.js.map +1 -0
  192. package/dist/lib/utils.d.ts +7 -0
  193. package/dist/lib/utils.d.ts.map +1 -0
  194. package/dist/lib/utils.js +10 -0
  195. package/dist/lib/utils.js.map +1 -0
  196. package/dist/marketing/footer.d.ts +31 -0
  197. package/dist/marketing/footer.d.ts.map +1 -0
  198. package/dist/marketing/footer.js +9 -0
  199. package/dist/marketing/footer.js.map +1 -0
  200. package/dist/marketing/hero.d.ts +29 -0
  201. package/dist/marketing/hero.d.ts.map +1 -0
  202. package/dist/marketing/hero.js +7 -0
  203. package/dist/marketing/hero.js.map +1 -0
  204. package/dist/marketing/index.d.ts +21 -0
  205. package/dist/marketing/index.d.ts.map +1 -0
  206. package/dist/marketing/index.js +21 -0
  207. package/dist/marketing/index.js.map +1 -0
  208. package/dist/marketing/logo-cloud.d.ts +15 -0
  209. package/dist/marketing/logo-cloud.d.ts.map +1 -0
  210. package/dist/marketing/logo-cloud.js +6 -0
  211. package/dist/marketing/logo-cloud.js.map +1 -0
  212. package/dist/marketing/nav.d.ts +33 -0
  213. package/dist/marketing/nav.d.ts.map +1 -0
  214. package/dist/marketing/nav.js +14 -0
  215. package/dist/marketing/nav.js.map +1 -0
  216. package/dist/marketing/prose.d.ts +12 -0
  217. package/dist/marketing/prose.d.ts.map +1 -0
  218. package/dist/marketing/prose.js +18 -0
  219. package/dist/marketing/prose.js.map +1 -0
  220. package/dist/marketing/section.d.ts +22 -0
  221. package/dist/marketing/section.d.ts.map +1 -0
  222. package/dist/marketing/section.js +7 -0
  223. package/dist/marketing/section.js.map +1 -0
  224. package/dist/showcase/components/code-block.d.ts +11 -0
  225. package/dist/showcase/components/code-block.d.ts.map +1 -0
  226. package/dist/showcase/components/code-block.js +20 -0
  227. package/dist/showcase/components/code-block.js.map +1 -0
  228. package/dist/showcase/components/example.d.ts +16 -0
  229. package/dist/showcase/components/example.d.ts.map +1 -0
  230. package/dist/showcase/components/example.js +14 -0
  231. package/dist/showcase/components/example.js.map +1 -0
  232. package/dist/showcase/components/section.d.ts +21 -0
  233. package/dist/showcase/components/section.d.ts.map +1 -0
  234. package/dist/showcase/components/section.js +10 -0
  235. package/dist/showcase/components/section.js.map +1 -0
  236. package/dist/showcase/components/swatch.d.ts +17 -0
  237. package/dist/showcase/components/swatch.d.ts.map +1 -0
  238. package/dist/showcase/components/swatch.js +6 -0
  239. package/dist/showcase/components/swatch.js.map +1 -0
  240. package/dist/showcase/index.d.ts +17 -0
  241. package/dist/showcase/index.d.ts.map +1 -0
  242. package/dist/showcase/index.js +17 -0
  243. package/dist/showcase/index.js.map +1 -0
  244. package/dist/showcase/page.d.ts +2 -0
  245. package/dist/showcase/page.d.ts.map +1 -0
  246. package/dist/showcase/page.js +1085 -0
  247. package/dist/showcase/page.js.map +1 -0
  248. package/dist/styles/generated/tokens.d.ts +131 -0
  249. package/dist/styles/generated/tokens.d.ts.map +1 -0
  250. package/dist/styles/generated/tokens.js +107 -0
  251. package/dist/styles/generated/tokens.js.map +1 -0
  252. package/dist/styles/globals.css +131 -0
  253. package/dist/styles/tailwind.preset.d.ts +181 -0
  254. package/dist/styles/tailwind.preset.d.ts.map +1 -0
  255. package/dist/styles/tailwind.preset.js +114 -0
  256. package/dist/styles/tailwind.preset.js.map +1 -0
  257. package/dist/tokens/index.d.ts +176 -0
  258. package/dist/tokens/index.d.ts.map +1 -0
  259. package/dist/tokens/index.js +139 -0
  260. package/dist/tokens/index.js.map +1 -0
  261. package/dist/tokens/tokens.json +154 -0
  262. package/package.json +124 -0
  263. package/src/components/accordion.tsx +76 -0
  264. package/src/components/alert.tsx +113 -0
  265. package/src/components/app-shell.tsx +43 -0
  266. package/src/components/aspect-ratio.tsx +18 -0
  267. package/src/components/avatar-group.tsx +73 -0
  268. package/src/components/avatar.tsx +81 -0
  269. package/src/components/badge.tsx +77 -0
  270. package/src/components/breadcrumb.tsx +121 -0
  271. package/src/components/button.tsx +83 -0
  272. package/src/components/calendar.tsx +85 -0
  273. package/src/components/capacity-bar.tsx +80 -0
  274. package/src/components/card.tsx +104 -0
  275. package/src/components/checkbox.tsx +46 -0
  276. package/src/components/chip.tsx +74 -0
  277. package/src/components/collapsible.tsx +54 -0
  278. package/src/components/combobox.tsx +140 -0
  279. package/src/components/confirm-action.tsx +111 -0
  280. package/src/components/container.tsx +39 -0
  281. package/src/components/date-picker.tsx +98 -0
  282. package/src/components/dialog.tsx +174 -0
  283. package/src/components/drawer.tsx +157 -0
  284. package/src/components/dropdown-menu.tsx +200 -0
  285. package/src/components/empty-state.tsx +46 -0
  286. package/src/components/form-field.tsx +118 -0
  287. package/src/components/input.tsx +29 -0
  288. package/src/components/label.tsx +35 -0
  289. package/src/components/live-pill.tsx +35 -0
  290. package/src/components/metric-tile.tsx +83 -0
  291. package/src/components/money-breakdown.tsx +92 -0
  292. package/src/components/number-input.tsx +113 -0
  293. package/src/components/pagination.tsx +157 -0
  294. package/src/components/popover.tsx +46 -0
  295. package/src/components/progress.tsx +34 -0
  296. package/src/components/radio-group.tsx +46 -0
  297. package/src/components/scroll-area.tsx +55 -0
  298. package/src/components/select.tsx +169 -0
  299. package/src/components/separator.tsx +34 -0
  300. package/src/components/sidebar.tsx +168 -0
  301. package/src/components/skeleton.tsx +85 -0
  302. package/src/components/slider.tsx +58 -0
  303. package/src/components/spec.tsx +59 -0
  304. package/src/components/spinner.tsx +36 -0
  305. package/src/components/stack.tsx +80 -0
  306. package/src/components/status-pill.tsx +100 -0
  307. package/src/components/switch.tsx +37 -0
  308. package/src/components/table.tsx +129 -0
  309. package/src/components/tabs.tsx +72 -0
  310. package/src/components/textarea.tsx +27 -0
  311. package/src/components/theme-provider.tsx +131 -0
  312. package/src/components/theme-toggle.tsx +34 -0
  313. package/src/components/three-state.tsx +90 -0
  314. package/src/components/timestamp.tsx +107 -0
  315. package/src/components/toaster.tsx +55 -0
  316. package/src/components/tooltip.tsx +49 -0
  317. package/src/components/top-bar.tsx +29 -0
  318. package/src/index.ts +221 -0
  319. package/src/lib/utils.ts +10 -0
  320. package/src/marketing/footer.tsx +93 -0
  321. package/src/marketing/hero.tsx +92 -0
  322. package/src/marketing/index.ts +24 -0
  323. package/src/marketing/logo-cloud.tsx +35 -0
  324. package/src/marketing/nav.tsx +122 -0
  325. package/src/marketing/prose.tsx +45 -0
  326. package/src/marketing/section.tsx +77 -0
  327. package/src/showcase/components/code-block.tsx +66 -0
  328. package/src/showcase/components/example.tsx +47 -0
  329. package/src/showcase/components/section.tsx +70 -0
  330. package/src/showcase/components/swatch.tsx +52 -0
  331. package/src/showcase/index.tsx +16 -0
  332. package/src/showcase/page.tsx +4216 -0
  333. package/src/styles/generated/tokens.ts +119 -0
  334. package/src/styles/globals.css +131 -0
  335. package/src/styles/tailwind.preset.ts +134 -0
  336. package/src/test/a11y.test.tsx +638 -0
  337. package/src/test/marketing-a11y.test.tsx +138 -0
  338. package/src/test/setup.ts +47 -0
  339. package/src/tokens/index.ts +154 -0
  340. package/src/tokens/tokens.json +154 -0
@@ -0,0 +1,28 @@
1
+ import * as React from "react";
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
3
+ /**
4
+ * Dialog — per design.md §10
5
+ * - Max width 480px default, override via className
6
+ * - 6px radius, 1px strong border, shadow-md
7
+ * - Backdrop: rgba(0,0,0,0.4) with 4px blur
8
+ * - Header text-md semibold, body text-sm
9
+ * - Actions right-aligned; accent CTA on the right, secondary on left
10
+ *
11
+ * Accessibility (provided by Radix):
12
+ * - Focus trap inside dialog
13
+ * - Escape closes
14
+ * - aria-labelledby / aria-describedby auto-wired via Title / Description
15
+ * - Returns focus to trigger on close
16
+ */
17
+ export declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
18
+ export declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
19
+ export declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
20
+ export declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
21
+ export declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
22
+ export declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
23
+ export declare function DialogHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
24
+ export declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
25
+ export declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
26
+ export declare function DialogBody({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
27
+ export declare function DialogFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
28
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAI1D;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,MAAM,uCAAuB,CAAC;AAC3C,eAAO,MAAM,aAAa,8GAA0B,CAAC;AACrD,eAAO,MAAM,YAAY,6CAAyB,CAAC;AACnD,eAAO,MAAM,WAAW,4GAAwB,CAAC;AAEjD,eAAO,MAAM,aAAa,8JAaxB,CAAC;AAGH,eAAO,MAAM,aAAa,8JAuDxB,CAAC;AAGH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,2CAOtC;AAED,eAAO,MAAM,WAAW,oKAYtB,CAAC;AAGH,eAAO,MAAM,iBAAiB,8KAS5B,CAAC;AAGH,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,2CAetC;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,2CAUtC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC;AACrD,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC;AACnD,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAG3C,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,eAAe,CAAC,OAAO,IACtB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,oDAAoD,EACpD,mCAAmC,EACnC,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAC;AACH,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC;AAEhE,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAG3C,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAC5C,MAAC,YAAY,eACX,KAAC,aAAa,KAAG,EAYjB,cAAK,SAAS,EAAC,+EAA+E,YAC5F,MAAC,eAAe,CAAC,OAAO,IACtB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE;gBACX,0DAA0D;gBAC1D,yDAAyD;gBACzD,qDAAqD;gBACrD,sDAAsD;gBACtD,kDAAkD;gBAClD,8DAA8D,EAC9D,kBAAkB;gBAClB,iDAAiD;gBACjD,0DAA0D;gBAC1D,oDAAoD;gBACpD,2BAA2B;gBAC3B,gEAAgE,EAChE,8DAA8D,EAC9D,sCAAsC,EACtC,SAAS,CACV,KACG,KAAK,aAER,QAAQ,EACT,KAAC,eAAe,CAAC,KAAK,IACpB,SAAS,EAAE,EAAE,CACX,mGAAmG,EACnG,4DAA4D,EAC5D,yEAAyE;wBACzE,uDAAuD;wBACvD,+DAA+D,CAChE,gBACU,cAAc,YAEzB,KAAC,CAAC,IAAC,SAAS,EAAC,SAAS,EAAC,WAAW,EAAE,IAAI,GAAI,GACtB,IACA,GACtB,IACO,CAChB,CAAC,CAAC;AACH,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC;AAEhE,MAAM,UAAU,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EAC6B;IACrC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CAAC,uCAAuC,EAAE,SAAS,CAAC,KAC7D,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAGzC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,eAAe,CAAC,KAAK,IACpB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,0DAA0D,EAC1D,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAC;AACH,WAAW,CAAC,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC;AAE5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,UAAU,CAG/C,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,eAAe,CAAC,WAAW,IAC1B,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,gCAAgC,EAAE,SAAS,CAAC,KACtD,KAAK,GACT,CACH,CAAC,CAAC;AACH,iBAAiB,CAAC,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,WAAW,CAAC;AAExE,MAAM,UAAU,UAAU,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EAC6B;IACrC,4DAA4D;IAC5D,6DAA6D;IAC7D,iEAAiE;IACjE,8DAA8D;IAC9D,uDAAuD;IACvD,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,kEAAkE,EAClE,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EAC6B;IACrC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,sFAAsF,EACtF,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
5
+ import { X } from "lucide-react";
6
+ import { cva } from "class-variance-authority";
7
+ import { cn } from "../lib/utils.js";
8
+ /**
9
+ * Drawer / Sheet — side-pushed panel for secondary tasks.
10
+ *
11
+ * Use a Drawer (not a Dialog) for:
12
+ * - Editing a row inline
13
+ * - Viewing details without losing place in the list
14
+ * - Mobile filter sheets
15
+ * - Audit timelines, side-by-side comparisons
16
+ *
17
+ * Per design.md §3.17, drawers replace modal stacks — never nest a
18
+ * dialog inside a drawer or vice versa.
19
+ *
20
+ * Backed by Radix Dialog under the hood, so focus trap, escape close,
21
+ * and aria semantics work out of the box.
22
+ */
23
+ export const Drawer = DialogPrimitive.Root;
24
+ export const DrawerTrigger = DialogPrimitive.Trigger;
25
+ export const DrawerClose = DialogPrimitive.Close;
26
+ export const DrawerPortal = DialogPrimitive.Portal;
27
+ export const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn("fixed inset-0 z-50 bg-black/40 backdrop-blur-[4px]", "data-[state=open]:animate-fade-in", className), ...props })));
28
+ DrawerOverlay.displayName = "DrawerOverlay";
29
+ export const drawerVariants = cva("fixed z-50 flex flex-col bg-background border-border-strong shadow-md outline-none transition-transform", {
30
+ variants: {
31
+ side: {
32
+ top: "inset-x-0 top-0 border-b max-h-[80vh] data-[state=open]:animate-fade-in",
33
+ bottom: "inset-x-0 bottom-0 border-t max-h-[80vh] data-[state=open]:animate-fade-in",
34
+ left: "inset-y-0 left-0 h-full w-80 border-r data-[state=open]:animate-fade-in",
35
+ right: "inset-y-0 right-0 h-full w-96 border-l data-[state=open]:animate-fade-in",
36
+ },
37
+ },
38
+ defaultVariants: { side: "right" },
39
+ });
40
+ export const DrawerContent = React.forwardRef(({ side = "right", className, children, ...props }, ref) => (_jsxs(DrawerPortal, { children: [_jsx(DrawerOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn(drawerVariants({ side }), className), ...props, children: [children, _jsx(DialogPrimitive.Close, { "aria-label": "Close drawer", className: "absolute right-3 top-3 inline-flex h-6 w-6 items-center justify-center rounded-sm text-text-muted transition-colors hover:bg-bg-subtle hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:after:absolute pointer-coarse:after:-inset-2.5", children: _jsx(X, { className: "h-4 w-4", strokeWidth: 1.75 }) })] })] })));
41
+ DrawerContent.displayName = "DrawerContent";
42
+ export function DrawerHeader({ className, ...props }) {
43
+ return (_jsx("div", { className: cn("px-5 pt-4 pb-3 border-b border-border", className), ...props }));
44
+ }
45
+ export const DrawerTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Title, { ref: ref, className: cn("text-md font-semibold tracking-[-0.01em] text-foreground", className), ...props })));
46
+ DrawerTitle.displayName = "DrawerTitle";
47
+ export const DrawerDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Description, { ref: ref, className: cn("text-xs text-text-muted mt-0.5", className), ...props })));
48
+ DrawerDescription.displayName = "DrawerDescription";
49
+ export function DrawerBody({ className, ...props }) {
50
+ return (_jsx("div", { className: cn("px-5 py-4 text-sm text-foreground overflow-y-auto flex-1", className), ...props }));
51
+ }
52
+ export function DrawerFooter({ className, ...props }) {
53
+ return (_jsx("div", { className: cn("flex items-center justify-end gap-2 px-5 py-3 border-t border-border bg-bg-subtle/50", className), ...props }));
54
+ }
55
+ //# sourceMappingURL=drawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawer.js","sourceRoot":"","sources":["../../src/components/drawer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import * as React from "react";
2
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
3
+ /**
4
+ * DropdownMenu — for actions menus (kebab on table rows, user avatar
5
+ * menu in topbar). NOT for selecting a value — use Select for that.
6
+ *
7
+ * <DropdownMenu>
8
+ * <DropdownMenuTrigger asChild><Button>Actions</Button></DropdownMenuTrigger>
9
+ * <DropdownMenuContent>
10
+ * <DropdownMenuLabel>Game</DropdownMenuLabel>
11
+ * <DropdownMenuItem>View roster</DropdownMenuItem>
12
+ * <DropdownMenuItem>Broadcast…</DropdownMenuItem>
13
+ * <DropdownMenuSeparator />
14
+ * <DropdownMenuItem className="text-danger">Cancel game…</DropdownMenuItem>
15
+ * </DropdownMenuContent>
16
+ * </DropdownMenu>
17
+ */
18
+ export declare const DropdownMenu: React.FC<DropdownMenuPrimitive.DropdownMenuProps>;
19
+ export declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
20
+ export declare const DropdownMenuGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & React.RefAttributes<HTMLDivElement>>;
21
+ export declare const DropdownMenuPortal: React.FC<DropdownMenuPrimitive.DropdownMenuPortalProps>;
22
+ export declare const DropdownMenuSub: React.FC<DropdownMenuPrimitive.DropdownMenuSubProps>;
23
+ export declare const DropdownMenuRadioGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuRadioGroupProps & React.RefAttributes<HTMLDivElement>>;
24
+ export declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
25
+ export declare const DropdownMenuItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
26
+ inset?: boolean;
27
+ } & React.RefAttributes<HTMLDivElement>>;
28
+ export declare const DropdownMenuCheckboxItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuCheckboxItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
29
+ export declare const DropdownMenuRadioItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuRadioItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
30
+ export declare const DropdownMenuLabel: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuLabelProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
31
+ inset?: boolean;
32
+ } & React.RefAttributes<HTMLDivElement>>;
33
+ export declare const DropdownMenuSeparator: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
34
+ export declare function DropdownMenuShortcut({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): import("react/jsx-runtime").JSX.Element;
35
+ export declare const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubTriggerProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
36
+ inset?: boolean;
37
+ } & React.RefAttributes<HTMLDivElement>>;
38
+ export declare const DropdownMenuSubContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
39
+ //# sourceMappingURL=dropdown-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-menu.d.ts","sourceRoot":"","sources":["../../src/components/dropdown-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,qBAAqB,MAAM,+BAA+B,CAAC;AAIvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,mDAA6B,CAAC;AACvD,eAAO,MAAM,mBAAmB,0HAAgC,CAAC;AACjE,eAAO,MAAM,iBAAiB,qHAA8B,CAAC;AAC7D,eAAO,MAAM,kBAAkB,yDAA+B,CAAC;AAC/D,eAAO,MAAM,eAAe,sDAA4B,CAAC;AACzD,eAAO,MAAM,sBAAsB,0HAAmC,CAAC;AAEvE,eAAO,MAAM,mBAAmB,0KAgB9B,CAAC;AAGH,eAAO,MAAM,gBAAgB;YAGjB,OAAO;wCAcjB,CAAC;AAGH,eAAO,MAAM,wBAAwB,+KAsBnC,CAAC;AAGH,eAAO,MAAM,qBAAqB,4KAqBhC,CAAC;AAGH,eAAO,MAAM,iBAAiB;YAGlB,OAAO;wCAYjB,CAAC;AAGH,eAAO,MAAM,qBAAqB,4KAShC,CAAC;AAGH,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,2CAUvC;AAED,eAAO,MAAM,sBAAsB;YAGvB,OAAO;wCAiBjB,CAAC;AAGH,eAAO,MAAM,sBAAsB,6KAajC,CAAC"}
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
5
+ import { Check, ChevronRight, Circle } from "lucide-react";
6
+ import { cn } from "../lib/utils.js";
7
+ /**
8
+ * DropdownMenu — for actions menus (kebab on table rows, user avatar
9
+ * menu in topbar). NOT for selecting a value — use Select for that.
10
+ *
11
+ * <DropdownMenu>
12
+ * <DropdownMenuTrigger asChild><Button>Actions</Button></DropdownMenuTrigger>
13
+ * <DropdownMenuContent>
14
+ * <DropdownMenuLabel>Game</DropdownMenuLabel>
15
+ * <DropdownMenuItem>View roster</DropdownMenuItem>
16
+ * <DropdownMenuItem>Broadcast…</DropdownMenuItem>
17
+ * <DropdownMenuSeparator />
18
+ * <DropdownMenuItem className="text-danger">Cancel game…</DropdownMenuItem>
19
+ * </DropdownMenuContent>
20
+ * </DropdownMenu>
21
+ */
22
+ export const DropdownMenu = DropdownMenuPrimitive.Root;
23
+ export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
24
+ export const DropdownMenuGroup = DropdownMenuPrimitive.Group;
25
+ export const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
26
+ export const DropdownMenuSub = DropdownMenuPrimitive.Sub;
27
+ export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
28
+ export const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { ref: ref, sideOffset: sideOffset, className: cn("z-50 min-w-[8rem] overflow-hidden rounded border border-border-strong bg-background text-foreground shadow-md p-1", "data-[state=open]:animate-fade-in", className), ...props }) })));
29
+ DropdownMenuContent.displayName = "DropdownMenuContent";
30
+ export const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (_jsx(DropdownMenuPrimitive.Item, { ref: ref, className: cn("relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 pointer-coarse:min-h-11 text-sm outline-none transition-colors", "focus:bg-bg-subtle focus:text-foreground", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", inset && "pl-8", className), ...props })));
31
+ DropdownMenuItem.displayName = "DropdownMenuItem";
32
+ export const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (_jsxs(DropdownMenuPrimitive.CheckboxItem, { ref: ref, className: cn("relative flex cursor-default select-none items-center rounded-sm py-1.5 pointer-coarse:min-h-11 pl-8 pr-2 text-sm outline-none transition-colors", "focus:bg-bg-subtle focus:text-foreground", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className), checked: checked, ...props, children: [_jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(Check, { className: "h-3 w-3", strokeWidth: 2.5 }) }) }), children] })));
33
+ DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
34
+ export const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(DropdownMenuPrimitive.RadioItem, { ref: ref, className: cn("relative flex cursor-default select-none items-center rounded-sm py-1.5 pointer-coarse:min-h-11 pl-8 pr-2 text-sm outline-none transition-colors", "focus:bg-bg-subtle focus:text-foreground", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className), ...props, children: [_jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(Circle, { className: "h-1.5 w-1.5 fill-current", strokeWidth: 0 }) }) }), children] })));
35
+ DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
36
+ export const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (_jsx(DropdownMenuPrimitive.Label, { ref: ref, className: cn("px-2 py-1.5 text-[10px] font-semibold uppercase tracking-[0.06em] text-text-muted", inset && "pl-8", className), ...props })));
37
+ DropdownMenuLabel.displayName = "DropdownMenuLabel";
38
+ export const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx(DropdownMenuPrimitive.Separator, { ref: ref, className: cn("-mx-1 my-1 h-px bg-border", className), ...props })));
39
+ DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
40
+ export function DropdownMenuShortcut({ className, ...props }) {
41
+ return (_jsx("span", { className: cn("ml-auto text-[10px] font-mono tracking-widest text-text-subtle tabular", className), ...props }));
42
+ }
43
+ export const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (_jsxs(DropdownMenuPrimitive.SubTrigger, { ref: ref, className: cn("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 pointer-coarse:min-h-11 text-sm outline-none transition-colors", "focus:bg-bg-subtle focus:text-foreground", "data-[state=open]:bg-bg-subtle", inset && "pl-8", className), ...props, children: [children, _jsx(ChevronRight, { className: "ml-auto h-3 w-3", strokeWidth: 1.75 })] })));
44
+ DropdownMenuSubTrigger.displayName = "DropdownMenuSubTrigger";
45
+ export const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (_jsx(DropdownMenuPrimitive.SubContent, { ref: ref, className: cn("z-50 min-w-[8rem] overflow-hidden rounded border border-border-strong bg-background text-foreground shadow-md p-1", "data-[state=open]:animate-fade-in", className), ...props })));
46
+ DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
47
+ //# sourceMappingURL=dropdown-menu.js.map
@@ -0,0 +1,15 @@
1
+ import * as React from "react";
2
+ /**
3
+ * EmptyState — per design.md §10
4
+ * - Centered, single line text-sm muted
5
+ * - Optional small CTA
6
+ * - NO illustrations. A subtle Lucide icon at most.
7
+ */
8
+ export interface EmptyStateProps extends React.HTMLAttributes<HTMLDivElement> {
9
+ icon?: React.ReactNode;
10
+ title: string;
11
+ description?: string;
12
+ action?: React.ReactNode;
13
+ }
14
+ export declare function EmptyState({ icon, title, description, action, className, ...props }: EmptyStateProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=empty-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;;;;GAKG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAED,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,MAAM,EACN,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,2CAsBjB"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ export function EmptyState({ icon, title, description, action, className, ...props }) {
4
+ return (_jsxs("div", { role: "status", className: cn("flex flex-col items-center justify-center gap-2 px-6 py-10 text-center", className), ...props, children: [icon && (_jsx("div", { className: "text-text-subtle mb-1", "aria-hidden": "true", children: icon })), _jsx("div", { className: "text-sm font-medium text-foreground", children: title }), description && (_jsx("div", { className: "text-xs text-text-muted max-w-xs", children: description })), action && _jsx("div", { className: "mt-2", children: action })] }));
5
+ }
6
+ //# sourceMappingURL=empty-state.js.map
@@ -0,0 +1,32 @@
1
+ import * as React from "react";
2
+ /**
3
+ * FormField — composition wrapper that auto-wires Label + control +
4
+ * helper/error text + the right aria attributes.
5
+ *
6
+ * <FormField label="Email" required helper="We'll send confirmations here.">
7
+ * <Input type="email" autoComplete="email" />
8
+ * </FormField>
9
+ *
10
+ * <FormField label="Card" required error="Card number is too short.">
11
+ * <Input />
12
+ * </FormField>
13
+ *
14
+ * The child input is cloned with: `id`, `aria-describedby`, `aria-invalid`,
15
+ * so consumers don't have to remember the a11y plumbing.
16
+ */
17
+ export interface FormFieldProps {
18
+ /** Optional explicit id — autogenerated if omitted. */
19
+ id?: string;
20
+ label?: React.ReactNode;
21
+ required?: boolean;
22
+ helper?: React.ReactNode;
23
+ error?: React.ReactNode;
24
+ /** Hide label visually but keep for screen readers */
25
+ hideLabel?: boolean;
26
+ /** Inline layout — label sits on the left of the control */
27
+ inline?: boolean;
28
+ className?: string;
29
+ children: React.ReactNode;
30
+ }
31
+ export declare function FormField({ id, label, required, helper, error, hideLabel, inline, className, children, }: FormFieldProps): import("react/jsx-runtime").JSX.Element;
32
+ //# sourceMappingURL=form-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-field.d.ts","sourceRoot":"","sources":["../../src/components/form-field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,SAAS,CAAC,EACxB,EAAE,EACF,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAM,EACN,SAAS,EACT,QAAQ,GACT,EAAE,cAAc,2CAwEhB"}
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../lib/utils.js";
5
+ export function FormField({ id, label, required, helper, error, hideLabel, inline, className, children, }) {
6
+ const reactId = React.useId();
7
+ const fieldId = id ?? reactId;
8
+ const helperId = `${fieldId}-helper`;
9
+ const errorId = `${fieldId}-error`;
10
+ const describedBy = [error ? errorId : null, helper && !error ? helperId : null]
11
+ .filter(Boolean)
12
+ .join(" ") || undefined;
13
+ // Clone first valid child so we can inject id + aria props.
14
+ const child = React.Children.map(children, (c) => {
15
+ if (!React.isValidElement(c))
16
+ return c;
17
+ const el = c;
18
+ return React.cloneElement(el, {
19
+ id: el.props.id ?? fieldId,
20
+ "aria-describedby": el.props["aria-describedby"] ?? describedBy,
21
+ "aria-invalid": el.props["aria-invalid"] ?? (error ? true : undefined),
22
+ });
23
+ });
24
+ const labelEl = label && (_jsxs("label", { htmlFor: fieldId, className: cn("block text-xs font-medium uppercase tracking-[0.04em] text-text-muted", hideLabel && "sr-only"), children: [label, required && (_jsx("span", { "aria-hidden": "true", className: "ml-0.5 text-danger", children: "*" }))] }));
25
+ const messages = error || helper ? (_jsx("p", { id: error ? errorId : helperId, className: cn("text-xs", error ? "text-danger" : "text-text-muted"), children: error ?? helper })) : null;
26
+ if (inline) {
27
+ return (_jsxs("div", { className: cn("flex items-start gap-3", className), children: [labelEl && _jsx("div", { className: "pt-1.5 w-32 shrink-0", children: labelEl }), _jsxs("div", { className: "flex-1 min-w-0 space-y-1", children: [child, messages] })] }));
28
+ }
29
+ return (_jsxs("div", { className: cn("space-y-1.5", className), children: [labelEl, child, messages] }));
30
+ }
31
+ //# sourceMappingURL=form-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-field.js","sourceRoot":"","sources":["../../src/components/form-field.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAgClC,MAAM,UAAU,SAAS,CAAC,EACxB,EAAE,EACF,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAM,EACN,SAAS,EACT,QAAQ,GACO;IACf,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,EAAE,IAAI,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,GAAG,OAAO,SAAS,CAAC;IACrC,MAAM,OAAO,GAAG,GAAG,OAAO,QAAQ,CAAC;IAEnC,MAAM,WAAW,GACf,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;SACzD,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;IAE5B,4DAA4D;IAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;QAC/C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QACvC,MAAM,EAAE,GAAG,CAIT,CAAC;QACH,OAAO,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE;YAC5B,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,OAAO;YAC1B,kBAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,WAAW;YAC/D,cAAc,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;SACvE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,KAAK,IAAI,CACvB,iBACE,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,EAAE,CACX,uEAAuE,EACvE,SAAS,IAAI,SAAS,CACvB,aAEA,KAAK,EACL,QAAQ,IAAI,CACX,8BAAkB,MAAM,EAAC,SAAS,EAAC,oBAAoB,kBAEhD,CACR,IACK,CACT,CAAC;IAEF,MAAM,QAAQ,GACZ,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAChB,YACE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAC9B,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,YAElE,KAAK,IAAI,MAAM,GACd,CACL,CAAC,CAAC,CAAC,IAAI,CAAC;IAEX,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,wBAAwB,EAAE,SAAS,CAAC,aACpD,OAAO,IAAI,cAAK,SAAS,EAAC,sBAAsB,YAAE,OAAO,GAAO,EACjE,eAAK,SAAS,EAAC,0BAA0B,aACtC,KAAK,EACL,QAAQ,IACL,IACF,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,aAAa,EAAE,SAAS,CAAC,aACzC,OAAO,EACP,KAAK,EACL,QAAQ,IACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Input — per design.md §10
4
+ * Height 32px, padding 0 10px, 1px border-strong, 2px radius.
5
+ * Focus: 2px ring in the theme ring color (no border color change).
6
+ * Error: pass `aria-invalid` true → border + ring switch to danger.
7
+ */
8
+ export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
9
+ export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
10
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;AAErE,eAAO,MAAM,KAAK,qFAgBjB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cn } from "../lib/utils.js";
4
+ export const Input = React.forwardRef(({ className, type = "text", ...props }, ref) => (_jsx("input", { ref: ref, type: type, className: cn("flex h-8 pointer-coarse:h-11 w-full rounded-sm border border-border-strong bg-background px-2.5 text-sm text-foreground transition-colors duration-150 ease-out", "placeholder:text-text-subtle", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "disabled:cursor-not-allowed disabled:bg-bg-muted disabled:opacity-60", "aria-[invalid=true]:border-danger aria-[invalid=true]:focus-visible:ring-danger", className), ...props })));
5
+ Input.displayName = "Input";
6
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAUlC,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CACnC,CAAC,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAC/C,gBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CACX,iKAAiK,EACjK,8BAA8B,EAC9B,yEAAyE,EACzE,sEAAsE,EACtE,iFAAiF,EACjF,SAAS,CACV,KACG,KAAK,GACT,CACH,CACF,CAAC;AACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC"}
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+ import * as LabelPrimitive from "@radix-ui/react-label";
3
+ /**
4
+ * Label — per design.md §10
5
+ * Uppercase, tracking-wide, text-xs, muted color.
6
+ * Always pair with its input via `htmlFor`.
7
+ */
8
+ export declare const Label: React.ForwardRefExoticComponent<Omit<LabelPrimitive.LabelProps & React.RefAttributes<HTMLLabelElement>, "ref"> & {
9
+ required?: boolean;
10
+ } & React.RefAttributes<HTMLLabelElement>>;
11
+ //# sourceMappingURL=label.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../src/components/label.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AAGxD;;;;GAIG;AACH,eAAO,MAAM,KAAK;eAGH,OAAO;0CAmBpB,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as LabelPrimitive from "@radix-ui/react-label";
5
+ import { cn } from "../lib/utils.js";
6
+ /**
7
+ * Label — per design.md §10
8
+ * Uppercase, tracking-wide, text-xs, muted color.
9
+ * Always pair with its input via `htmlFor`.
10
+ */
11
+ export const Label = React.forwardRef(({ className, children, required, ...props }, ref) => (_jsxs(LabelPrimitive.Root, { ref: ref, className: cn("block text-xs font-medium uppercase tracking-[0.04em] text-text-muted", "peer-disabled:cursor-not-allowed peer-disabled:opacity-60", className), ...props, children: [children, required && (_jsx("span", { "aria-hidden": "true", className: "ml-0.5 text-danger", children: "*" }))] })));
12
+ Label.displayName = "Label";
13
+ //# sourceMappingURL=label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.js","sourceRoot":"","sources":["../../src/components/label.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAKnC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACtD,MAAC,cAAc,CAAC,IAAI,IAClB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,uEAAuE,EACvE,2DAA2D,EAC3D,SAAS,CACV,KACG,KAAK,aAER,QAAQ,EACR,QAAQ,IAAI,CACX,8BAAkB,MAAM,EAAC,SAAS,EAAC,oBAAoB,kBAEhD,CACR,IACmB,CACvB,CAAC,CAAC;AACH,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC"}
@@ -0,0 +1,14 @@
1
+ import * as React from "react";
2
+ /**
3
+ * LivePill — per design.md §10 & §12
4
+ * The ONE continuously animated element in the system.
5
+ * Renders a lime pill with a pulsing dot and "LIVE" label.
6
+ *
7
+ * Accessibility:
8
+ * - aria-live="polite" so SR users hear "Live" without interrupting
9
+ * - The pulse animation honors prefers-reduced-motion via globals.css
10
+ */
11
+ export declare function LivePill({ className, label, ...props }: React.HTMLAttributes<HTMLSpanElement> & {
12
+ label?: string;
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=live-pill.d.ts.map
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ /**
4
+ * LivePill — per design.md §10 & §12
5
+ * The ONE continuously animated element in the system.
6
+ * Renders a lime pill with a pulsing dot and "LIVE" label.
7
+ *
8
+ * Accessibility:
9
+ * - aria-live="polite" so SR users hear "Live" without interrupting
10
+ * - The pulse animation honors prefers-reduced-motion via globals.css
11
+ */
12
+ export function LivePill({ className, label = "Live", ...props }) {
13
+ return (_jsxs("span", { role: "status", "aria-live": "polite", className: cn("inline-flex items-center gap-1.5 rounded-full bg-brand-lime px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.06em] text-brand-lime-foreground", className), ...props, children: [_jsx("span", { className: "block h-1.5 w-1.5 rounded-full bg-brand-lime-foreground animate-live-pulse", "aria-hidden": "true" }), label] }));
14
+ }
15
+ //# sourceMappingURL=live-pill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-pill.js","sourceRoot":"","sources":["../../src/components/live-pill.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,SAAS,EACT,KAAK,GAAG,MAAM,EACd,GAAG,KAAK,EACmD;IAC3D,OAAO,CACL,gBACE,IAAI,EAAC,QAAQ,eACH,QAAQ,EAClB,SAAS,EAAE,EAAE,CACX,0JAA0J,EAC1J,SAAS,CACV,KACG,KAAK,aAET,eACE,SAAS,EAAC,4EAA4E,iBAC1E,MAAM,GAClB,EACD,KAAK,IACD,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ /**
3
+ * MetricTile — per design.md §10
4
+ *
5
+ * Three lines exactly: label / value / delta.
6
+ * - label: text-xs uppercase muted
7
+ * - value: text-2xl semibold tabular
8
+ * - delta: text-xs forest (up) / danger (down) / muted (flat)
9
+ *
10
+ * Use 3–4 across in dashboard rows.
11
+ */
12
+ export interface MetricTileProps extends React.HTMLAttributes<HTMLDivElement> {
13
+ label: string;
14
+ value: React.ReactNode;
15
+ /** Numeric delta vs prior period. Sign and direction are derived. */
16
+ delta?: number;
17
+ /** Human-readable suffix appended to the delta, e.g. "vs last week" */
18
+ deltaLabel?: string;
19
+ /** Override the delta direction (e.g. when "up" is bad like refunds) */
20
+ invertDelta?: boolean;
21
+ }
22
+ export declare function MetricTile({ label, value, delta, deltaLabel, invertDelta, className, ...props }: MetricTileProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=metric-tile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-tile.d.ts","sourceRoot":"","sources":["../../src/components/metric-tile.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,KAAK,EACL,UAA2B,EAC3B,WAAmB,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,2CAiDjB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * MoneyBreakdown — implements design.md §3.15 Money UX.
3
+ *
4
+ * Always shown before any charge. Every line is named, signed, and
5
+ * tabular-aligned. The receipt component should render the same lines
6
+ * in the same order.
7
+ *
8
+ * Usage:
9
+ * <MoneyBreakdown
10
+ * lines={[
11
+ * { label: "Game fee", cents: 1400 },
12
+ * { label: "Credit applied", cents: -600, muted: true },
13
+ * { label: "Sales tax", cents: 70 },
14
+ * ]}
15
+ * totalLabel="Charged to card"
16
+ * totalCents={870}
17
+ * />
18
+ */
19
+ export interface MoneyLine {
20
+ label: string;
21
+ cents: number;
22
+ /** Render in muted text (for credit applied, taxes, etc.). */
23
+ muted?: boolean;
24
+ /** Optional hint shown under the label. */
25
+ hint?: string;
26
+ }
27
+ export interface MoneyBreakdownProps {
28
+ lines: MoneyLine[];
29
+ totalLabel?: string;
30
+ totalCents: number;
31
+ /** Currency code; default USD. */
32
+ currency?: string;
33
+ className?: string;
34
+ }
35
+ export declare function MoneyBreakdown({ lines, totalLabel, totalCents, currency, className, }: MoneyBreakdownProps): import("react/jsx-runtime").JSX.Element;
36
+ //# sourceMappingURL=money-breakdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-breakdown.d.ts","sourceRoot":"","sources":["../../src/components/money-breakdown.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,UAAoB,EACpB,UAAU,EACV,QAAgB,EAChB,SAAS,GACV,EAAE,mBAAmB,2CAwCrB"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ function fmt(cents, currency = "USD") {
4
+ return new Intl.NumberFormat("en-US", {
5
+ style: "currency",
6
+ currency,
7
+ }).format(cents / 100);
8
+ }
9
+ export function MoneyBreakdown({ lines, totalLabel = "Total", totalCents, currency = "USD", className, }) {
10
+ return (_jsxs("dl", { className: cn("rounded border border-border bg-background", className), children: [lines.map((line, i) => (_jsxs("div", { className: "flex items-start justify-between gap-4 px-4 py-2.5 border-b border-border last:border-b-0", children: [_jsxs("dt", { className: cn("text-sm", line.muted ? "text-text-muted" : "text-foreground"), children: [line.label, line.hint && (_jsx("span", { className: "block text-xs text-text-subtle mt-0.5", children: line.hint }))] }), _jsxs("dd", { className: cn("tabular text-sm", line.muted ? "text-text-muted" : "text-foreground"), children: [line.cents < 0 ? "−" : "", fmt(Math.abs(line.cents), currency)] })] }, i))), _jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3 bg-bg-subtle border-t border-border", children: [_jsx("dt", { className: "text-sm font-semibold", children: totalLabel }), _jsx("dd", { className: "tabular text-md font-semibold", children: fmt(totalCents, currency) })] })] }));
11
+ }
12
+ //# sourceMappingURL=money-breakdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-breakdown.js","sourceRoot":"","sources":["../../src/components/money-breakdown.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAsClC,SAAS,GAAG,CAAC,KAAa,EAAE,QAAQ,GAAG,KAAK;IAC1C,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;QACpC,KAAK,EAAE,UAAU;QACjB,QAAQ;KACT,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAC7B,KAAK,EACL,UAAU,GAAG,OAAO,EACpB,UAAU,EACV,QAAQ,GAAG,KAAK,EAChB,SAAS,GACW;IACpB,OAAO,CACL,cAAI,SAAS,EAAE,EAAE,CAAC,4CAA4C,EAAE,SAAS,CAAC,aACvE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,eAEE,SAAS,EAAC,2FAA2F,aAErG,cACE,SAAS,EAAE,EAAE,CACX,SAAS,EACT,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CACnD,aAEA,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,IAAI,IAAI,CACZ,eAAM,SAAS,EAAC,uCAAuC,YACpD,IAAI,CAAC,IAAI,GACL,CACR,IACE,EACL,cACE,SAAS,EAAE,EAAE,CACX,iBAAiB,EACjB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CACnD,aAEA,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EACzB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,IACjC,KAxBA,CAAC,CAyBF,CACP,CAAC,EACF,eAAK,SAAS,EAAC,uFAAuF,aACpG,aAAI,SAAS,EAAC,uBAAuB,YAAE,UAAU,GAAM,EACvD,aAAI,SAAS,EAAC,+BAA+B,YAC1C,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,GACvB,IACD,IACH,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import * as React from "react";
2
+ /**
3
+ * NumberInput — stepper-style numeric input with explicit +/− buttons.
4
+ * Use for: capacity, min-to-run, price (in cents or units), quantity.
5
+ *
6
+ * Decimals: pass `step={0.5}` etc. Always set min/max for safe bounds.
7
+ */
8
+ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "type"> {
9
+ value?: number;
10
+ onChange?: (value: number) => void;
11
+ min?: number;
12
+ max?: number;
13
+ step?: number;
14
+ }
15
+ export declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
16
+ //# sourceMappingURL=number-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/components/number-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;GAKG;AACH,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,UAAU,GAAG,OAAO,GAAG,MAAM,CAC9B;IACC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,2FAwFvB,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Minus, Plus } from "lucide-react";
5
+ import { cn } from "../lib/utils.js";
6
+ export const NumberInput = React.forwardRef(({ value, onChange, min, max, step = 1, className, disabled, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, id, ...rest }, ref) => {
7
+ const clamp = (v) => {
8
+ let next = v;
9
+ if (min !== undefined && next < min)
10
+ next = min;
11
+ if (max !== undefined && next > max)
12
+ next = max;
13
+ return next;
14
+ };
15
+ const handleChange = (next) => {
16
+ onChange?.(clamp(next));
17
+ };
18
+ const cur = value ?? 0;
19
+ const decDisabled = disabled || (min !== undefined && cur <= min);
20
+ const incDisabled = disabled || (max !== undefined && cur >= max);
21
+ return (_jsxs("div", { className: cn("inline-flex h-8 items-stretch rounded-sm border border-border-strong overflow-hidden",
22
+ // 44px control height + stepper width on touch devices.
23
+ "pointer-coarse:h-11", "aria-[invalid=true]:border-danger", disabled && "opacity-50 pointer-events-none", className), "aria-invalid": ariaInvalid, children: [_jsx("button", { type: "button", "aria-label": "Decrease", onClick: () => handleChange(cur - step), disabled: decDisabled, className: "w-7 pointer-coarse:w-11 grid place-items-center text-text-muted hover:bg-bg-subtle hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed border-r border-border-strong", children: _jsx(Minus, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }) }), _jsx("input", { ref: ref, id: id, type: "number", inputMode: "numeric", value: value ?? "", onChange: (e) => {
24
+ const n = e.target.value === "" ? NaN : Number(e.target.value);
25
+ if (!Number.isNaN(n))
26
+ handleChange(n);
27
+ }, min: min, max: max, step: step, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, className: cn("w-16 text-center text-sm font-medium tabular bg-background text-foreground", "focus:outline-none focus-visible:bg-bg-subtle", "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"), ...rest }), _jsx("button", { type: "button", "aria-label": "Increase", onClick: () => handleChange(cur + step), disabled: incDisabled, className: "w-7 pointer-coarse:w-11 grid place-items-center text-text-muted hover:bg-bg-subtle hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed border-l border-border-strong", children: _jsx(Plus, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }) })] }));
28
+ });
29
+ NumberInput.displayName = "NumberInput";
30
+ //# sourceMappingURL=number-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.js","sourceRoot":"","sources":["../../src/components/number-input.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Pagination — page navigation for tables and lists.
4
+ *
5
+ * <Pagination
6
+ * currentPage={page}
7
+ * totalPages={totalPages}
8
+ * onPageChange={setPage}
9
+ * />
10
+ *
11
+ * Renders previous / page numbers (with ellipses for large counts) / next.
12
+ * Use only when total > 1; for <= 10 pages no ellipses are inserted.
13
+ *
14
+ * For URL-driven pagination (per design.md §3.9), pass an onPageChange
15
+ * that calls router.replace(?page=N).
16
+ */
17
+ export interface PaginationProps extends React.HTMLAttributes<HTMLElement> {
18
+ currentPage: number;
19
+ totalPages: number;
20
+ onPageChange: (page: number) => void;
21
+ /** Number of pages to show on each side of the current page. */
22
+ siblingCount?: number;
23
+ /** Disable interaction (e.g., while fetching). */
24
+ disabled?: boolean;
25
+ }
26
+ export declare const Pagination: React.ForwardRefExoticComponent<PaginationProps & React.RefAttributes<HTMLElement>>;
27
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/components/pagination.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,qFAwEtB,CAAC"}