@franco_roura/module-01 0.0.0-stage → 1.0.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 (222) hide show
  1. package/LICENSE-APACHE +202 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +64 -2
  4. package/dist/charts.d.ts +3 -0
  5. package/dist/charts.js +3 -0
  6. package/dist/components/alert-dialog.d.ts +19 -0
  7. package/dist/components/alert-dialog.js +101 -0
  8. package/dist/components/alert-dialog.js.map +1 -0
  9. package/dist/components/amount.d.ts +24 -0
  10. package/dist/components/amount.js +27 -0
  11. package/dist/components/amount.js.map +1 -0
  12. package/dist/components/appearance-pickers.d.ts +9 -0
  13. package/dist/components/appearance-pickers.js +65 -0
  14. package/dist/components/appearance-pickers.js.map +1 -0
  15. package/dist/components/badge.d.ts +10 -0
  16. package/dist/components/badge.js +28 -0
  17. package/dist/components/badge.js.map +1 -0
  18. package/dist/components/budget-meter.d.ts +18 -0
  19. package/dist/components/budget-meter.js +38 -0
  20. package/dist/components/budget-meter.js.map +1 -0
  21. package/dist/components/button.d.ts +13 -0
  22. package/dist/components/button.js +54 -0
  23. package/dist/components/button.js.map +1 -0
  24. package/dist/components/calendar.d.ts +7 -0
  25. package/dist/components/calendar.js +52 -0
  26. package/dist/components/calendar.js.map +1 -0
  27. package/dist/components/category-icon.d.ts +33 -0
  28. package/dist/components/category-icon.js +49 -0
  29. package/dist/components/category-icon.js.map +1 -0
  30. package/dist/components/chart.d.ts +44 -0
  31. package/dist/components/chart.js +147 -0
  32. package/dist/components/chart.js.map +1 -0
  33. package/dist/components/charts.d.ts +52 -0
  34. package/dist/components/charts.js +482 -0
  35. package/dist/components/charts.js.map +1 -0
  36. package/dist/components/checkbox.d.ts +5 -0
  37. package/dist/components/checkbox.js +21 -0
  38. package/dist/components/checkbox.js.map +1 -0
  39. package/dist/components/combobox.d.ts +32 -0
  40. package/dist/components/combobox.js +100 -0
  41. package/dist/components/combobox.js.map +1 -0
  42. package/dist/components/command.d.ts +19 -0
  43. package/dist/components/command.js +86 -0
  44. package/dist/components/command.js.map +1 -0
  45. package/dist/components/cta-banner.d.ts +14 -0
  46. package/dist/components/cta-banner.js +39 -0
  47. package/dist/components/cta-banner.js.map +1 -0
  48. package/dist/components/date-picker.d.ts +19 -0
  49. package/dist/components/date-picker.js +107 -0
  50. package/dist/components/date-picker.js.map +1 -0
  51. package/dist/components/dialog.d.ts +18 -0
  52. package/dist/components/dialog.js +99 -0
  53. package/dist/components/dialog.js.map +1 -0
  54. package/dist/components/dropdown-menu.d.ts +26 -0
  55. package/dist/components/dropdown-menu.js +123 -0
  56. package/dist/components/dropdown-menu.js.map +1 -0
  57. package/dist/components/field.d.ts +30 -0
  58. package/dist/components/field.js +53 -0
  59. package/dist/components/field.js.map +1 -0
  60. package/dist/components/footer.d.ts +18 -0
  61. package/dist/components/footer.js +40 -0
  62. package/dist/components/footer.js.map +1 -0
  63. package/dist/components/fx-converter.d.ts +22 -0
  64. package/dist/components/fx-converter.js +91 -0
  65. package/dist/components/fx-converter.js.map +1 -0
  66. package/dist/components/hero.d.ts +28 -0
  67. package/dist/components/hero.js +83 -0
  68. package/dist/components/hero.js.map +1 -0
  69. package/dist/components/hud.d.ts +41 -0
  70. package/dist/components/hud.js +108 -0
  71. package/dist/components/hud.js.map +1 -0
  72. package/dist/components/input.d.ts +4 -0
  73. package/dist/components/input.js +14 -0
  74. package/dist/components/input.js.map +1 -0
  75. package/dist/components/label.d.ts +5 -0
  76. package/dist/components/label.js +15 -0
  77. package/dist/components/label.js.map +1 -0
  78. package/dist/components/media-card.d.ts +29 -0
  79. package/dist/components/media-card.js +80 -0
  80. package/dist/components/media-card.js.map +1 -0
  81. package/dist/components/money-input.d.ts +10 -0
  82. package/dist/components/money-input.js +30 -0
  83. package/dist/components/money-input.js.map +1 -0
  84. package/dist/components/multi-combobox.d.ts +27 -0
  85. package/dist/components/multi-combobox.js +101 -0
  86. package/dist/components/multi-combobox.js.map +1 -0
  87. package/dist/components/nav-bar.d.ts +21 -0
  88. package/dist/components/nav-bar.js +44 -0
  89. package/dist/components/nav-bar.js.map +1 -0
  90. package/dist/components/panel.d.ts +27 -0
  91. package/dist/components/panel.js +49 -0
  92. package/dist/components/panel.js.map +1 -0
  93. package/dist/components/popover.d.ts +11 -0
  94. package/dist/components/popover.js +56 -0
  95. package/dist/components/popover.js.map +1 -0
  96. package/dist/components/select.d.ts +16 -0
  97. package/dist/components/select.js +128 -0
  98. package/dist/components/select.js.map +1 -0
  99. package/dist/components/separator.d.ts +5 -0
  100. package/dist/components/separator.js +17 -0
  101. package/dist/components/separator.js.map +1 -0
  102. package/dist/components/sheet.d.ts +15 -0
  103. package/dist/components/sheet.js +87 -0
  104. package/dist/components/sheet.js.map +1 -0
  105. package/dist/components/skeleton.d.ts +3 -0
  106. package/dist/components/skeleton.js +13 -0
  107. package/dist/components/skeleton.js.map +1 -0
  108. package/dist/components/sonner.d.ts +5 -0
  109. package/dist/components/sonner.js +44 -0
  110. package/dist/components/sonner.js.map +1 -0
  111. package/dist/components/spec-readout.d.ts +11 -0
  112. package/dist/components/spec-readout.js +25 -0
  113. package/dist/components/spec-readout.js.map +1 -0
  114. package/dist/components/split-flap.d.ts +12 -0
  115. package/dist/components/split-flap.js +77 -0
  116. package/dist/components/split-flap.js.map +1 -0
  117. package/dist/components/tabs.d.ts +12 -0
  118. package/dist/components/tabs.js +47 -0
  119. package/dist/components/tabs.js.map +1 -0
  120. package/dist/components/tag.d.ts +16 -0
  121. package/dist/components/tag.js +26 -0
  122. package/dist/components/tag.js.map +1 -0
  123. package/dist/components/terminal.d.ts +10 -0
  124. package/dist/components/terminal.js +20 -0
  125. package/dist/components/terminal.js.map +1 -0
  126. package/dist/components/textarea.d.ts +4 -0
  127. package/dist/components/textarea.js +13 -0
  128. package/dist/components/textarea.js.map +1 -0
  129. package/dist/components/timeline-entry.d.ts +26 -0
  130. package/dist/components/timeline-entry.js +63 -0
  131. package/dist/components/timeline-entry.js.map +1 -0
  132. package/dist/components/toggle-group.d.ts +10 -0
  133. package/dist/components/toggle-group.js +49 -0
  134. package/dist/components/toggle-group.js.map +1 -0
  135. package/dist/components/toggle.d.ts +10 -0
  136. package/dist/components/toggle.js +37 -0
  137. package/dist/components/toggle.js.map +1 -0
  138. package/dist/components/tooltip.d.ts +8 -0
  139. package/dist/components/tooltip.js +36 -0
  140. package/dist/components/tooltip.js.map +1 -0
  141. package/dist/finance.d.ts +10 -0
  142. package/dist/finance.js +10 -0
  143. package/dist/index.d.ts +33 -0
  144. package/dist/index.js +33 -0
  145. package/dist/lib/category-icons.d.ts +80 -0
  146. package/dist/lib/category-icons.js +102 -0
  147. package/dist/lib/category-icons.js.map +1 -0
  148. package/dist/lib/fault.d.ts +7 -0
  149. package/dist/lib/fault.js +28 -0
  150. package/dist/lib/fault.js.map +1 -0
  151. package/dist/lib/form-flow.d.ts +15 -0
  152. package/dist/lib/form-flow.js +50 -0
  153. package/dist/lib/form-flow.js.map +1 -0
  154. package/dist/lib/fx.d.ts +39 -0
  155. package/dist/lib/fx.js +98 -0
  156. package/dist/lib/fx.js.map +1 -0
  157. package/dist/lib/money.d.ts +19 -0
  158. package/dist/lib/money.js +55 -0
  159. package/dist/lib/money.js.map +1 -0
  160. package/dist/lib/use-media-query.d.ts +3 -0
  161. package/dist/lib/use-media-query.js +15 -0
  162. package/dist/lib/use-media-query.js.map +1 -0
  163. package/dist/lib/utils.d.ts +3 -0
  164. package/dist/lib/utils.js +26 -0
  165. package/dist/lib/utils.js.map +1 -0
  166. package/dist/site.d.ts +10 -0
  167. package/dist/site.js +10 -0
  168. package/dist/styles.css +2 -0
  169. package/dist/theme.css +391 -0
  170. package/dist/tokens.css +181 -0
  171. package/guidelines/AlertDialog.md +9 -0
  172. package/guidelines/Amount.md +10 -0
  173. package/guidelines/AppearancePickers.md +8 -0
  174. package/guidelines/Badge.md +11 -0
  175. package/guidelines/BudgetMeter.md +11 -0
  176. package/guidelines/Button.md +16 -0
  177. package/guidelines/Calendar.md +8 -0
  178. package/guidelines/CategoryIcon.md +10 -0
  179. package/guidelines/Charts.md +12 -0
  180. package/guidelines/Checkbox.md +8 -0
  181. package/guidelines/Combobox.md +18 -0
  182. package/guidelines/Command.md +8 -0
  183. package/guidelines/Crosshair.md +7 -0
  184. package/guidelines/CtaBanner.md +8 -0
  185. package/guidelines/DatePicker.md +11 -0
  186. package/guidelines/Dialog.md +9 -0
  187. package/guidelines/DropdownMenu.md +9 -0
  188. package/guidelines/Field.md +22 -0
  189. package/guidelines/Footer.md +7 -0
  190. package/guidelines/FxConverter.md +12 -0
  191. package/guidelines/GlassPanel.md +8 -0
  192. package/guidelines/Grill.md +7 -0
  193. package/guidelines/Hero.md +9 -0
  194. package/guidelines/HudLabel.md +8 -0
  195. package/guidelines/Input.md +9 -0
  196. package/guidelines/Label.md +7 -0
  197. package/guidelines/MediaCard.md +8 -0
  198. package/guidelines/MoneyInput.md +10 -0
  199. package/guidelines/MultiCombobox.md +11 -0
  200. package/guidelines/NavBar.md +10 -0
  201. package/guidelines/Panel.md +10 -0
  202. package/guidelines/Popover.md +8 -0
  203. package/guidelines/README.md +100 -0
  204. package/guidelines/SectionHeader.md +9 -0
  205. package/guidelines/Select.md +9 -0
  206. package/guidelines/Separator.md +8 -0
  207. package/guidelines/Sheet.md +9 -0
  208. package/guidelines/Skeleton.md +8 -0
  209. package/guidelines/SpecReadout.md +7 -0
  210. package/guidelines/SplitFlap.md +9 -0
  211. package/guidelines/StatusLed.md +8 -0
  212. package/guidelines/Tabs.md +9 -0
  213. package/guidelines/Tag.md +9 -0
  214. package/guidelines/Terminal.md +7 -0
  215. package/guidelines/Textarea.md +8 -0
  216. package/guidelines/TickRuler.md +8 -0
  217. package/guidelines/TimelineEntry.md +8 -0
  218. package/guidelines/Toaster.md +9 -0
  219. package/guidelines/Toggle.md +9 -0
  220. package/guidelines/Tooltip.md +8 -0
  221. package/package.json +103 -4
  222. package/tokens/tokens.json +739 -0
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { DropdownMenu } from "radix-ui";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
6
+ // src/components/dropdown-menu.tsx
7
+ function DropdownMenu$1({ ...props }) {
8
+ return /* @__PURE__ */ jsx(DropdownMenu.Root, {
9
+ "data-slot": "dropdown-menu",
10
+ ...props
11
+ });
12
+ }
13
+ function DropdownMenuPortal({ ...props }) {
14
+ return /* @__PURE__ */ jsx(DropdownMenu.Portal, {
15
+ "data-slot": "dropdown-menu-portal",
16
+ ...props
17
+ });
18
+ }
19
+ function DropdownMenuTrigger({ ...props }) {
20
+ return /* @__PURE__ */ jsx(DropdownMenu.Trigger, {
21
+ "data-slot": "dropdown-menu-trigger",
22
+ ...props
23
+ });
24
+ }
25
+ function DropdownMenuContent({ className, sideOffset = 4, ...props }) {
26
+ return /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx(DropdownMenu.Content, {
27
+ "data-slot": "dropdown-menu-content",
28
+ sideOffset,
29
+ className: cn("z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-float data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", className),
30
+ ...props
31
+ }) });
32
+ }
33
+ function DropdownMenuGroup({ ...props }) {
34
+ return /* @__PURE__ */ jsx(DropdownMenu.Group, {
35
+ "data-slot": "dropdown-menu-group",
36
+ ...props
37
+ });
38
+ }
39
+ function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
40
+ return /* @__PURE__ */ jsx(DropdownMenu.Item, {
41
+ "data-slot": "dropdown-menu-item",
42
+ "data-inset": inset,
43
+ "data-variant": variant,
44
+ className: cn("relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!", className),
45
+ ...props
46
+ });
47
+ }
48
+ function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
49
+ return /* @__PURE__ */ jsxs(DropdownMenu.CheckboxItem, {
50
+ "data-slot": "dropdown-menu-checkbox-item",
51
+ className: cn("relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
52
+ checked,
53
+ ...props,
54
+ children: [/* @__PURE__ */ jsx("span", {
55
+ className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
56
+ children: /* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
57
+ }), children]
58
+ });
59
+ }
60
+ function DropdownMenuRadioGroup({ ...props }) {
61
+ return /* @__PURE__ */ jsx(DropdownMenu.RadioGroup, {
62
+ "data-slot": "dropdown-menu-radio-group",
63
+ ...props
64
+ });
65
+ }
66
+ function DropdownMenuRadioItem({ className, children, ...props }) {
67
+ return /* @__PURE__ */ jsxs(DropdownMenu.RadioItem, {
68
+ "data-slot": "dropdown-menu-radio-item",
69
+ className: cn("relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
70
+ ...props,
71
+ children: [/* @__PURE__ */ jsx("span", {
72
+ className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
73
+ children: /* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) })
74
+ }), children]
75
+ });
76
+ }
77
+ function DropdownMenuLabel({ className, inset, ...props }) {
78
+ return /* @__PURE__ */ jsx(DropdownMenu.Label, {
79
+ "data-slot": "dropdown-menu-label",
80
+ "data-inset": inset,
81
+ className: cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className),
82
+ ...props
83
+ });
84
+ }
85
+ function DropdownMenuSeparator({ className, ...props }) {
86
+ return /* @__PURE__ */ jsx(DropdownMenu.Separator, {
87
+ "data-slot": "dropdown-menu-separator",
88
+ className: cn("-mx-1 my-1 h-px bg-border", className),
89
+ ...props
90
+ });
91
+ }
92
+ function DropdownMenuShortcut({ className, ...props }) {
93
+ return /* @__PURE__ */ jsx("span", {
94
+ "data-slot": "dropdown-menu-shortcut",
95
+ className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
96
+ ...props
97
+ });
98
+ }
99
+ function DropdownMenuSub({ ...props }) {
100
+ return /* @__PURE__ */ jsx(DropdownMenu.Sub, {
101
+ "data-slot": "dropdown-menu-sub",
102
+ ...props
103
+ });
104
+ }
105
+ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
106
+ return /* @__PURE__ */ jsxs(DropdownMenu.SubTrigger, {
107
+ "data-slot": "dropdown-menu-sub-trigger",
108
+ "data-inset": inset,
109
+ className: cn("flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
110
+ ...props,
111
+ children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })]
112
+ });
113
+ }
114
+ function DropdownMenuSubContent({ className, ...props }) {
115
+ return /* @__PURE__ */ jsx(DropdownMenu.SubContent, {
116
+ "data-slot": "dropdown-menu-sub-content",
117
+ className: cn("z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-float data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", className),
118
+ ...props
119
+ });
120
+ }
121
+ export { DropdownMenu$1 as DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
122
+
123
+ //# sourceMappingURL=dropdown-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-menu.js","names":["DropdownMenu","DropdownMenuPrimitive"],"sources":["../../src/components/dropdown-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../lib/utils\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\n\nfunction DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-float data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\"ml-auto text-xs tracking-widest text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-float data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n};\n"],"mappings":";;;;;;AAOA,SAASA,eAAa,EAAE,GAAG,SAAkE;CAC3F,OAAO,oBAACC,aAAsB,MAAvB;EAA4B,aAAU;EAAgB,GAAI;CAAQ,CAAA;AAC3E;AAEA,SAAS,mBAAmB,EAC1B,GAAG,SACyD;CAC5D,OAAO,oBAACA,aAAsB,QAAvB;EAA8B,aAAU;EAAuB,GAAI;CAAQ,CAAA;AACpF;AAEA,SAAS,oBAAoB,EAC3B,GAAG,SAC0D;CAC7D,OAAO,oBAACA,aAAsB,SAAvB;EAA+B,aAAU;EAAwB,GAAI;CAAQ,CAAA;AACtF;AAEA,SAAS,oBAAoB,EAC3B,WACA,aAAa,GACb,GAAG,SAC0D;CAC7D,OACE,oBAACA,aAAsB,QAAvB,EAAA,UACE,oBAACA,aAAsB,SAAvB;EACE,aAAU;EACE;EACZ,WAAW,GACT,6jBACA,SACF;EACA,GAAI;CACL,CAAA,EAC2B,CAAA;AAElC;AAEA,SAAS,kBAAkB,EAAE,GAAG,SAAmE;CACjG,OAAO,oBAACA,aAAsB,OAAvB;EAA6B,aAAU;EAAsB,GAAI;CAAQ,CAAA;AAClF;AAEA,SAAS,iBAAiB,EACxB,WACA,OACA,UAAU,WACV,GAAG,SAIF;CACD,OACE,oBAACA,aAAsB,MAAvB;EACE,aAAU;EACV,cAAY;EACZ,gBAAc;EACd,WAAW,GACT,ujBACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,yBAAyB,EAChC,WACA,UACA,SACA,GAAG,SAC+D;CAClE,OACE,qBAACA,aAAsB,cAAvB;EACE,aAAU;EACV,WAAW,GACT,gTACA,SACF;EACS;EACT,GAAI;EAPN,UAAA,CASE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAACA,aAAsB,eAAvB,EAAA,UACE,oBAAC,WAAD,EAAW,WAAU,SAAU,CAAA,EACI,CAAA;EACjC,CAAA,GACL,QACiC;;AAExC;AAEA,SAAS,uBAAuB,EAC9B,GAAG,SAC6D;CAChE,OAAO,oBAACA,aAAsB,YAAvB;EAAkC,aAAU;EAA4B,GAAI;CAAQ,CAAA;AAC7F;AAEA,SAAS,sBAAsB,EAC7B,WACA,UACA,GAAG,SAC4D;CAC/D,OACE,qBAACA,aAAsB,WAAvB;EACE,aAAU;EACV,WAAW,GACT,gTACA,SACF;EACA,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAACA,aAAsB,eAAvB,EAAA,UACE,oBAAC,YAAD,EAAY,WAAU,sBAAuB,CAAA,EACV,CAAA;EACjC,CAAA,GACL,QAC8B;;AAErC;AAEA,SAAS,kBAAkB,EACzB,WACA,OACA,GAAG,SAGF;CACD,OACE,oBAACA,aAAsB,OAAvB;EACE,aAAU;EACV,cAAY;EACZ,WAAW,GAAG,qDAAqD,SAAS;EAC5E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,sBAAsB,EAC7B,WACA,GAAG,SAC4D;CAC/D,OACE,oBAACA,aAAsB,WAAvB;EACE,aAAU;EACV,WAAW,GAAG,6BAA6B,SAAS;EACpD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,qBAAqB,EAAE,WAAW,GAAG,SAAuC;CACnF,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,yDAAyD,SAAS;EAChF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,GAAG,SAAiE;CAC7F,OAAO,oBAACA,aAAsB,KAAvB;EAA2B,aAAU;EAAoB,GAAI;CAAQ,CAAA;AAC9E;AAEA,SAAS,uBAAuB,EAC9B,WACA,OACA,UACA,GAAG,SAGF;CACD,OACE,qBAACA,aAAsB,YAAvB;EACE,aAAU;EACV,cAAY;EACZ,WAAW,GACT,8WACA,SACF;EACA,GAAI;EAPN,UAAA,CASG,UACD,oBAAC,kBAAD,EAAkB,WAAU,iBAAkB,CAAA,CACd;;AAEtC;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACA,aAAsB,YAAvB;EACE,aAAU;EACV,WAAW,GACT,ofACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,30 @@
1
+ import * as React from "react";
2
+ /** The fault LED: a small danger dot with a tint halo that blinks as it appears. */
3
+ export declare function FaultLed({ className }: {
4
+ className?: string;
5
+ }): React.JSX.Element;
6
+ /**
7
+ * Announces an error to screen readers without showing a line under the control; the visible
8
+ * cue is the red label with its fault LED. Renders nothing without children.
9
+ */
10
+ export declare function FieldError({ children }: {
11
+ children?: React.ReactNode;
12
+ }): React.JSX.Element | null;
13
+ /** Field label; when invalid it turns danger with a fault LED in front. */
14
+ export declare function FieldLabel({ htmlFor, invalid, className, children }: {
15
+ htmlFor?: string;
16
+ invalid?: boolean;
17
+ className?: string;
18
+ children: React.ReactNode;
19
+ }): React.JSX.Element;
20
+ /** Label + control + help text, stacked. Pass the control's id as `htmlFor`. */
21
+ export declare function Field({ label, htmlFor, error, help, className, children }: {
22
+ label: React.ReactNode;
23
+ htmlFor?: string;
24
+ /** Turns the label red with a fault LED; the message is announced, not shown. */
25
+ error?: React.ReactNode;
26
+ help?: React.ReactNode;
27
+ className?: string;
28
+ children: React.ReactNode;
29
+ }): React.JSX.Element;
30
+ //# sourceMappingURL=field.d.ts.map
@@ -0,0 +1,53 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Label } from "./label.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ // src/components/field.tsx
5
+ /** The fault LED: a small danger dot with a tint halo that blinks as it appears. */
6
+ function FaultLed({ className }) {
7
+ return /* @__PURE__ */ jsx("span", {
8
+ "aria-hidden": true,
9
+ className: cn("led-blink inline-block size-1.5 shrink-0 rounded-full bg-danger shadow-[0_0_0_3px_var(--color-danger-tint)]", className)
10
+ });
11
+ }
12
+ /**
13
+ * Announces an error to screen readers without showing a line under the control; the visible
14
+ * cue is the red label with its fault LED. Renders nothing without children.
15
+ */
16
+ function FieldError({ children }) {
17
+ if (!children) return null;
18
+ return /* @__PURE__ */ jsx("span", {
19
+ role: "alert",
20
+ className: "sr-only",
21
+ children
22
+ });
23
+ }
24
+ /** Field label; when invalid it turns danger with a fault LED in front. */
25
+ function FieldLabel({ htmlFor, invalid, className, children }) {
26
+ return /* @__PURE__ */ jsxs(Label, {
27
+ htmlFor,
28
+ "data-invalid": invalid || void 0,
29
+ className: cn("text-body-sm", invalid ? "text-danger" : "text-ink-soft", className),
30
+ children: [invalid && /* @__PURE__ */ jsx(FaultLed, {}), children]
31
+ });
32
+ }
33
+ /** Label + control + help text, stacked. Pass the control's id as `htmlFor`. */
34
+ function Field({ label, htmlFor, error, help, className, children }) {
35
+ return /* @__PURE__ */ jsxs("div", {
36
+ className: cn("flex min-w-0 flex-col gap-1.5", className),
37
+ children: [
38
+ /* @__PURE__ */ jsx(FieldLabel, {
39
+ htmlFor,
40
+ invalid: Boolean(error),
41
+ children: label
42
+ }),
43
+ children,
44
+ error ? /* @__PURE__ */ jsx(FieldError, { children: error }) : help ? /* @__PURE__ */ jsx("p", {
45
+ className: "text-body-sm text-ink-soft",
46
+ children: help
47
+ }) : null
48
+ ]
49
+ });
50
+ }
51
+ export { FaultLed, Field, FieldError, FieldLabel };
52
+
53
+ //# sourceMappingURL=field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field.js","names":[],"sources":["../../src/components/field.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport type * as React from \"react\";\nimport { Label } from \"./label\";\n\n/** The fault LED: a small danger dot with a tint halo that blinks as it appears. */\nexport function FaultLed({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={cn(\n \"led-blink inline-block size-1.5 shrink-0 rounded-full bg-danger shadow-[0_0_0_3px_var(--color-danger-tint)]\",\n className,\n )}\n />\n );\n}\n\n/**\n * Announces an error to screen readers without showing a line under the control; the visible\n * cue is the red label with its fault LED. Renders nothing without children.\n */\nexport function FieldError({ children }: { children?: React.ReactNode }) {\n if (!children) return null;\n return (\n <span role=\"alert\" className=\"sr-only\">\n {children}\n </span>\n );\n}\n\n/** Field label; when invalid it turns danger with a fault LED in front. */\nexport function FieldLabel({\n htmlFor,\n invalid,\n className,\n children,\n}: {\n htmlFor?: string;\n invalid?: boolean;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <Label\n htmlFor={htmlFor}\n data-invalid={invalid || undefined}\n className={cn(\"text-body-sm\", invalid ? \"text-danger\" : \"text-ink-soft\", className)}\n >\n {invalid && <FaultLed />}\n {children}\n </Label>\n );\n}\n\n/** Label + control + help text, stacked. Pass the control's id as `htmlFor`. */\nexport function Field({\n label,\n htmlFor,\n error,\n help,\n className,\n children,\n}: {\n label: React.ReactNode;\n htmlFor?: string;\n /** Turns the label red with a fault LED; the message is announced, not shown. */\n error?: React.ReactNode;\n help?: React.ReactNode;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-1.5\", className)}>\n <FieldLabel htmlFor={htmlFor} invalid={Boolean(error)}>\n {label}\n </FieldLabel>\n {children}\n {error ? (\n <FieldError>{error}</FieldError>\n ) : help ? (\n <p className=\"text-body-sm text-ink-soft\">{help}</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,SAAS,EAAE,aAAqC;CAC9D,OACE,oBAAC,QAAD;EACE,eAAA;EACA,WAAW,GACT,+GACA,SACF;CACD,CAAA;AAEL;;;;;AAMA,SAAgB,WAAW,EAAE,YAA4C;CACvE,IAAI,CAAC,UAAU,OAAO;CACtB,OACE,oBAAC,QAAD;EAAM,MAAK;EAAQ,WAAU;EAC1B;CACG,CAAA;AAEV;;AAGA,SAAgB,WAAW,EACzB,SACA,SACA,WACA,YAMC;CACD,OACE,qBAAC,OAAD;EACW;EACT,gBAAc,WAAW,KAAA;EACzB,WAAW,GAAG,gBAAgB,UAAU,gBAAgB,iBAAiB,SAAS;EAHpF,UAAA,CAKG,WAAW,oBAAC,UAAD,CAAW,CAAA,GACtB,QACI;;AAEX;;AAGA,SAAgB,MAAM,EACpB,OACA,SACA,OACA,MACA,WACA,YASC;CACD,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,iCAAiC,SAAS;EAA7D,UAAA;GACE,oBAAC,YAAD;IAAqB;IAAS,SAAS,QAAQ,KAAK;IACjD,UAAA;GACS,CAAA;GACX;GACA,QACC,oBAAC,YAAD,EAAA,UAAa,MAAkB,CAAA,IAC7B,OACF,oBAAC,KAAD;IAAG,WAAU;IAA8B,UAAA;GAAQ,CAAA,IACjD;EACD;;AAET"}
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ export type FooterLink = {
3
+ label: string;
4
+ href: string;
5
+ target?: string;
6
+ };
7
+ export type FooterProps = {
8
+ links?: FooterLink[];
9
+ /** Microprint on the left, e.g. a build stamp. */
10
+ left?: React.ReactNode;
11
+ /** Microprint on the right, e.g. coordinates. */
12
+ right?: React.ReactNode;
13
+ rulerLabels?: string[];
14
+ className?: string;
15
+ };
16
+ /** Page footer: a tick ruler, then microprint either side of bracketed links. */
17
+ export declare function Footer({ links, left, right, rulerLabels, className }: FooterProps): React.JSX.Element;
18
+ //# sourceMappingURL=footer.d.ts.map
@@ -0,0 +1,40 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Button } from "./button.js";
3
+ import { TickRuler } from "./hud.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ // src/components/footer.tsx
6
+ /** Page footer: a tick ruler, then microprint either side of bracketed links. */
7
+ function Footer({ links, left, right, rulerLabels, className }) {
8
+ return /* @__PURE__ */ jsxs("footer", {
9
+ className: cn("flex flex-col gap-4 pt-8 pb-6", className),
10
+ children: [/* @__PURE__ */ jsx(TickRuler, { labels: rulerLabels }), /* @__PURE__ */ jsxs("div", {
11
+ className: "flex flex-wrap items-center justify-between gap-6",
12
+ children: [
13
+ /* @__PURE__ */ jsx("span", {
14
+ className: "hud-sm text-ink-soft",
15
+ children: left
16
+ }),
17
+ /* @__PURE__ */ jsx("div", {
18
+ className: "flex flex-wrap gap-1",
19
+ children: links?.map((link) => /* @__PURE__ */ jsx(Button, {
20
+ variant: "bracket",
21
+ asChild: true,
22
+ children: /* @__PURE__ */ jsx("a", {
23
+ href: link.href,
24
+ target: link.target,
25
+ rel: link.target === "_blank" ? "noopener noreferrer" : void 0,
26
+ children: link.label
27
+ })
28
+ }, link.label))
29
+ }),
30
+ /* @__PURE__ */ jsx("span", {
31
+ className: "hud-sm text-ink-soft",
32
+ children: right
33
+ })
34
+ ]
35
+ })]
36
+ });
37
+ }
38
+ export { Footer };
39
+
40
+ //# sourceMappingURL=footer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footer.js","names":[],"sources":["../../src/components/footer.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { TickRuler } from \"./hud\";\n\nexport type FooterLink = {\n label: string;\n href: string;\n target?: string;\n};\n\nexport type FooterProps = {\n links?: FooterLink[];\n /** Microprint on the left, e.g. a build stamp. */\n left?: React.ReactNode;\n /** Microprint on the right, e.g. coordinates. */\n right?: React.ReactNode;\n rulerLabels?: string[];\n className?: string;\n};\n\n/** Page footer: a tick ruler, then microprint either side of bracketed links. */\nexport function Footer({ links, left, right, rulerLabels, className }: FooterProps) {\n return (\n <footer className={cn(\"flex flex-col gap-4 pt-8 pb-6\", className)}>\n <TickRuler labels={rulerLabels} />\n <div className=\"flex flex-wrap items-center justify-between gap-6\">\n <span className=\"hud-sm text-ink-soft\">{left}</span>\n <div className=\"flex flex-wrap gap-1\">\n {links?.map((link) => (\n <Button key={link.label} variant=\"bracket\" asChild>\n <a\n href={link.href}\n target={link.target}\n rel={link.target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n >\n {link.label}\n </a>\n </Button>\n ))}\n </div>\n <span className=\"hud-sm text-ink-soft\">{right}</span>\n </div>\n </footer>\n );\n}\n"],"mappings":";;;;;;AAsBA,SAAgB,OAAO,EAAE,OAAO,MAAM,OAAO,aAAa,aAA0B;CAClF,OACE,qBAAC,UAAD;EAAQ,WAAW,GAAG,iCAAiC,SAAS;EAAhE,UAAA,CACE,oBAAC,WAAD,EAAW,QAAQ,YAAc,CAAA,GACjC,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,oBAAC,QAAD;KAAM,WAAU;KAAwB,UAAA;IAAW,CAAA;IACnD,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,OAAO,KAAK,SACX,oBAAC,QAAD;MAAyB,SAAQ;MAAU,SAAA;MACzC,UAAA,oBAAC,KAAD;OACE,MAAM,KAAK;OACX,QAAQ,KAAK;OACb,KAAK,KAAK,WAAW,WAAW,wBAAwB,KAAA;OAEvD,UAAA,KAAK;MACL,CAAA;KACG,GARK,KAAK,KAQV,CACT;IACE,CAAA;IACL,oBAAC,QAAD;KAAM,WAAU;KAAwB,UAAA;IAAY,CAAA;GACjD;EACC,CAAA,CAAA;;AAEZ"}
@@ -0,0 +1,22 @@
1
+ import { FxState } from "../lib/fx.js";
2
+ type Currency = {
3
+ code: string;
4
+ minorUnits: number;
5
+ };
6
+ /**
7
+ * Three linked inputs for a cross-currency transfer: amount sent, amount received and rate.
8
+ * Editing one recomputes the least recently edited of the other two (see lib/fx.ts).
9
+ * Controlled: keep the FxState in the parent (start from `initialFxState()`).
10
+ */
11
+ export declare function FxConverter({ id: rootId, from, to, value, onChange, invalid, className }: {
12
+ /** Id of the root, e.g. to fault all three fields with `fault(id)`. */
13
+ id?: string;
14
+ from: Currency;
15
+ to: Currency;
16
+ value: FxState;
17
+ onChange: (next: FxState) => void;
18
+ invalid?: boolean;
19
+ className?: string;
20
+ }): import("react").JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=fx-converter.d.ts.map
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { editFx } from "../lib/fx.js";
3
+ import { cn } from "../lib/utils.js";
4
+ import { FieldLabel } from "./field.js";
5
+ import { MoneyInput } from "./money-input.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { useId } from "react";
8
+ // src/components/fx-converter.tsx
9
+ /**
10
+ * Three linked inputs for a cross-currency transfer: amount sent, amount received and rate.
11
+ * Editing one recomputes the least recently edited of the other two (see lib/fx.ts).
12
+ * Controlled: keep the FxState in the parent (start from `initialFxState()`).
13
+ */
14
+ function FxConverter({ id: rootId, from, to, value, onChange, invalid, className }) {
15
+ const id = useId();
16
+ const c = {
17
+ fromMinorUnits: from.minorUnits,
18
+ toMinorUnits: to.minorUnits
19
+ };
20
+ const edit = (field) => (e) => onChange(editFx(value, field, e.target.value, c));
21
+ const next = value.order[0];
22
+ return /* @__PURE__ */ jsx("div", {
23
+ id: rootId,
24
+ "data-fault-group": true,
25
+ className: cn("@container", className),
26
+ children: /* @__PURE__ */ jsxs("div", {
27
+ className: "grid gap-3 @lg:grid-cols-3",
28
+ children: [
29
+ /* @__PURE__ */ jsx(FxRow, {
30
+ id: `${id}-from`,
31
+ label: `Sent (${from.code})`,
32
+ computed: next === "from",
33
+ invalid,
34
+ children: /* @__PURE__ */ jsx(MoneyInput, {
35
+ id: `${id}-from`,
36
+ currency: from.code,
37
+ value: value.from,
38
+ onChange: edit("from"),
39
+ "aria-invalid": invalid || void 0
40
+ })
41
+ }),
42
+ /* @__PURE__ */ jsx(FxRow, {
43
+ id: `${id}-to`,
44
+ label: `Received (${to.code})`,
45
+ computed: next === "to",
46
+ invalid,
47
+ children: /* @__PURE__ */ jsx(MoneyInput, {
48
+ id: `${id}-to`,
49
+ currency: to.code,
50
+ value: value.to,
51
+ onChange: edit("to"),
52
+ "aria-invalid": invalid || void 0
53
+ })
54
+ }),
55
+ /* @__PURE__ */ jsx(FxRow, {
56
+ id: `${id}-rate`,
57
+ label: `Rate (${to.code} per ${from.code})`,
58
+ computed: next === "rate",
59
+ invalid,
60
+ children: /* @__PURE__ */ jsx(MoneyInput, {
61
+ id: `${id}-rate`,
62
+ currency: "×",
63
+ placeholder: "0.000000",
64
+ value: value.rate,
65
+ onChange: edit("rate"),
66
+ "aria-invalid": invalid || void 0
67
+ })
68
+ })
69
+ ]
70
+ })
71
+ });
72
+ }
73
+ function FxRow({ id, label, computed, invalid, children }) {
74
+ return /* @__PURE__ */ jsxs("div", {
75
+ className: "flex min-w-0 flex-col gap-1.5",
76
+ children: [/* @__PURE__ */ jsxs("div", {
77
+ className: "flex items-baseline justify-between gap-2",
78
+ children: [/* @__PURE__ */ jsx(FieldLabel, {
79
+ htmlFor: id,
80
+ invalid,
81
+ children: label
82
+ }), computed && /* @__PURE__ */ jsx("span", {
83
+ className: "hud-sm text-hud-mark",
84
+ children: "auto"
85
+ })]
86
+ }), children]
87
+ });
88
+ }
89
+ export { FxConverter };
90
+
91
+ //# sourceMappingURL=fx-converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-converter.js","names":[],"sources":["../../src/components/fx-converter.tsx"],"sourcesContent":["\"use client\";\n\nimport { editFx, type FxCurrencies, type FxField, type FxState } from \"../lib/fx\";\nimport { cn } from \"../lib/utils\";\nimport { useId } from \"react\";\nimport { FieldLabel } from \"./field\";\nimport { MoneyInput } from \"./money-input\";\n\ntype Currency = { code: string; minorUnits: number };\n\n/**\n * Three linked inputs for a cross-currency transfer: amount sent, amount received and rate.\n * Editing one recomputes the least recently edited of the other two (see lib/fx.ts).\n * Controlled: keep the FxState in the parent (start from `initialFxState()`).\n */\nexport function FxConverter({\n id: rootId,\n from,\n to,\n value,\n onChange,\n invalid,\n className,\n}: {\n /** Id of the root, e.g. to fault all three fields with `fault(id)`. */\n id?: string;\n from: Currency;\n to: Currency;\n value: FxState;\n onChange: (next: FxState) => void;\n invalid?: boolean;\n className?: string;\n}) {\n const id = useId();\n const c: FxCurrencies = { fromMinorUnits: from.minorUnits, toMinorUnits: to.minorUnits };\n const edit = (field: FxField) => (e: React.ChangeEvent<HTMLInputElement>) =>\n onChange(editFx(value, field, e.target.value, c));\n // The field that will be recomputed next is the oldest one; mark it so users can see it.\n const next = value.order[0];\n\n // Columns follow the converter's own width (it lives in sheets and narrow cards), not the viewport.\n return (\n <div id={rootId} data-fault-group className={cn(\"@container\", className)}>\n <div className=\"grid gap-3 @lg:grid-cols-3\">\n <FxRow\n id={`${id}-from`}\n label={`Sent (${from.code})`}\n computed={next === \"from\"}\n invalid={invalid}\n >\n <MoneyInput\n id={`${id}-from`}\n currency={from.code}\n value={value.from}\n onChange={edit(\"from\")}\n aria-invalid={invalid || undefined}\n />\n </FxRow>\n <FxRow\n id={`${id}-to`}\n label={`Received (${to.code})`}\n computed={next === \"to\"}\n invalid={invalid}\n >\n <MoneyInput\n id={`${id}-to`}\n currency={to.code}\n value={value.to}\n onChange={edit(\"to\")}\n aria-invalid={invalid || undefined}\n />\n </FxRow>\n <FxRow\n id={`${id}-rate`}\n label={`Rate (${to.code} per ${from.code})`}\n computed={next === \"rate\"}\n invalid={invalid}\n >\n <MoneyInput\n id={`${id}-rate`}\n currency=\"×\"\n placeholder=\"0.000000\"\n value={value.rate}\n onChange={edit(\"rate\")}\n aria-invalid={invalid || undefined}\n />\n </FxRow>\n </div>\n </div>\n );\n}\n\nfunction FxRow({\n id,\n label,\n computed,\n invalid,\n children,\n}: {\n id: string;\n label: string;\n computed: boolean;\n invalid?: boolean;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <FieldLabel htmlFor={id} invalid={invalid}>\n {label}\n </FieldLabel>\n {computed && <span className=\"hud-sm text-hud-mark\">auto</span>}\n </div>\n {children}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,SAAgB,YAAY,EAC1B,IAAI,QACJ,MACA,IACA,OACA,UACA,SACA,aAUC;CACD,MAAM,KAAK,MAAM;CACjB,MAAM,IAAkB;EAAE,gBAAgB,KAAK;EAAY,cAAc,GAAG;CAAW;CACvF,MAAM,QAAQ,WAAoB,MAChC,SAAS,OAAO,OAAO,OAAO,EAAE,OAAO,OAAO,CAAC,CAAC;CAElD,MAAM,OAAO,MAAM,MAAM;CAGzB,OACE,oBAAC,OAAD;EAAK,IAAI;EAAQ,oBAAA;EAAiB,WAAW,GAAG,cAAc,SAAS;EACrE,UAAA,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,oBAAC,OAAD;KACE,IAAI,GAAG,GAAG;KACV,OAAO,SAAS,KAAK,KAAK;KAC1B,UAAU,SAAS;KACV;KAET,UAAA,oBAAC,YAAD;MACE,IAAI,GAAG,GAAG;MACV,UAAU,KAAK;MACf,OAAO,MAAM;MACb,UAAU,KAAK,MAAM;MACrB,gBAAc,WAAW,KAAA;KAC1B,CAAA;IACI,CAAA;IACP,oBAAC,OAAD;KACE,IAAI,GAAG,GAAG;KACV,OAAO,aAAa,GAAG,KAAK;KAC5B,UAAU,SAAS;KACV;KAET,UAAA,oBAAC,YAAD;MACE,IAAI,GAAG,GAAG;MACV,UAAU,GAAG;MACb,OAAO,MAAM;MACb,UAAU,KAAK,IAAI;MACnB,gBAAc,WAAW,KAAA;KAC1B,CAAA;IACI,CAAA;IACP,oBAAC,OAAD;KACE,IAAI,GAAG,GAAG;KACV,OAAO,SAAS,GAAG,KAAK,OAAO,KAAK,KAAK;KACzC,UAAU,SAAS;KACV;KAET,UAAA,oBAAC,YAAD;MACE,IAAI,GAAG,GAAG;MACV,UAAS;MACT,aAAY;MACZ,OAAO,MAAM;MACb,UAAU,KAAK,MAAM;MACrB,gBAAc,WAAW,KAAA;KAC1B,CAAA;IACI,CAAA;GACJ;;CACF,CAAA;AAET;AAEA,SAAS,MAAM,EACb,IACA,OACA,UACA,SACA,YAOC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,YAAD;IAAY,SAAS;IAAa;IAC/B,UAAA;GACS,CAAA,GACX,YAAY,oBAAC,QAAD;IAAM,WAAU;IAAuB,UAAA;GAAU,CAAA,CAC3D;EACJ,CAAA,GAAA,QACE;;AAET"}
@@ -0,0 +1,28 @@
1
+ import { SpecItem } from "./spec-readout.js";
2
+ import * as React from "react";
3
+ export type HeroProps = {
4
+ /** The page title or product name, set in display-xl. One per page. */
5
+ title: React.ReactNode;
6
+ /** The line under the title, in HUD type: a tagline, a category, a role. */
7
+ subtitle?: React.ReactNode;
8
+ lead?: React.ReactNode;
9
+ /** Buttons under the lead. */
10
+ actions?: React.ReactNode;
11
+ specs?: SpecItem[];
12
+ /** An image for the studio frame: a product shot, a screenshot, a portrait. Without it the frame shows a crosshair. */
13
+ image?: React.ReactNode;
14
+ imageLabel?: string;
15
+ /** Replaces the studio frame and grill entirely. */
16
+ media?: React.ReactNode;
17
+ serial?: string;
18
+ coords?: string;
19
+ className?: string;
20
+ };
21
+ /** Studio-backdrop frame for the hero image, with an inner ring and a microprint tag. */
22
+ export declare function HeroFrame({ image, label }: {
23
+ image?: React.ReactNode;
24
+ label?: string;
25
+ }): React.JSX.Element;
26
+ /** The opening part of a page: title, subtitle, lead, actions and specs beside an image. */
27
+ export declare function Hero({ title, subtitle, lead, actions, specs, image, imageLabel, media, serial, coords, className }: HeroProps): React.JSX.Element;
28
+ //# sourceMappingURL=hero.d.ts.map
@@ -0,0 +1,83 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Crosshair, Grill } from "./hud.js";
3
+ import { SpecReadout } from "./spec-readout.js";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ // src/components/hero.tsx
6
+ /** Studio-backdrop frame for the hero image, with an inner ring and a microprint tag. */
7
+ function HeroFrame({ image, label }) {
8
+ return /* @__PURE__ */ jsxs("div", {
9
+ className: "relative flex h-60 w-50 items-center justify-center overflow-hidden rounded-md bg-studio [&>img]:size-full [&>img]:object-cover",
10
+ children: [
11
+ image ?? /* @__PURE__ */ jsx(Crosshair, { className: "size-5 text-ink/45" }),
12
+ /* @__PURE__ */ jsx("span", {
13
+ "aria-hidden": true,
14
+ className: "pointer-events-none absolute inset-3.5 rounded-sm shadow-[inset_0_0_0_1px_rgba(255,255,255,0.55)]"
15
+ }),
16
+ label && /* @__PURE__ */ jsx("span", {
17
+ className: "hud-sm absolute bottom-2.5 left-2.5 text-ink",
18
+ children: label
19
+ })
20
+ ]
21
+ });
22
+ }
23
+ /** The opening part of a page: title, subtitle, lead, actions and specs beside an image. */
24
+ function Hero({ title, subtitle, lead, actions, specs, image, imageLabel, media, serial, coords, className }) {
25
+ return /* @__PURE__ */ jsxs("section", {
26
+ className: cn("relative drop-float", className),
27
+ children: [/* @__PURE__ */ jsx("span", {
28
+ "aria-hidden": true,
29
+ className: "absolute -top-1.5 left-6 z-10 h-3 w-18 rounded-full bg-signal md:left-16"
30
+ }), /* @__PURE__ */ jsxs("div", {
31
+ className: "relative grid gap-12 rounded-xl bg-shell notch-lg px-6 pt-12 pb-8 md:grid-cols-[1fr_auto] md:px-16 md:pt-16 md:pb-12",
32
+ children: [
33
+ serial && /* @__PURE__ */ jsx("span", {
34
+ className: "hud-sm absolute top-6 left-6 text-hud-mark md:left-16",
35
+ children: serial
36
+ }),
37
+ /* @__PURE__ */ jsxs("div", {
38
+ className: "flex min-w-0 flex-col gap-6",
39
+ children: [
40
+ /* @__PURE__ */ jsx("h1", {
41
+ className: "font-display text-display-lg text-ink md:text-display-xl",
42
+ children: title
43
+ }),
44
+ subtitle && /* @__PURE__ */ jsx("p", {
45
+ className: "hud text-signal-ink",
46
+ children: subtitle
47
+ }),
48
+ lead && /* @__PURE__ */ jsx("p", {
49
+ className: "max-w-[36em] text-body-lg text-ink-soft",
50
+ children: lead
51
+ }),
52
+ actions && /* @__PURE__ */ jsx("div", {
53
+ className: "flex flex-wrap items-center gap-3",
54
+ children: actions
55
+ }),
56
+ specs && /* @__PURE__ */ jsx(SpecReadout, { items: specs })
57
+ ]
58
+ }),
59
+ /* @__PURE__ */ jsxs("div", {
60
+ className: "flex flex-col items-start gap-4 md:items-end",
61
+ children: [media ?? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HeroFrame, {
62
+ image,
63
+ label: imageLabel
64
+ }), /* @__PURE__ */ jsx(Grill, {
65
+ count: 4,
66
+ slotWidth: 28,
67
+ gap: "8px"
68
+ })] }), coords && /* @__PURE__ */ jsx("span", {
69
+ className: "hud-sm text-hud-mark",
70
+ children: coords
71
+ })]
72
+ }),
73
+ /* @__PURE__ */ jsx(Crosshair, {
74
+ tone: "signal",
75
+ className: "absolute right-3.5 bottom-3.5"
76
+ })
77
+ ]
78
+ })]
79
+ });
80
+ }
81
+ export { Hero, HeroFrame };
82
+
83
+ //# sourceMappingURL=hero.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero.js","names":[],"sources":["../../src/components/hero.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Crosshair, Grill } from \"./hud\";\nimport { type SpecItem, SpecReadout } from \"./spec-readout\";\n\nexport type HeroProps = {\n /** The page title or product name, set in display-xl. One per page. */\n title: React.ReactNode;\n /** The line under the title, in HUD type: a tagline, a category, a role. */\n subtitle?: React.ReactNode;\n lead?: React.ReactNode;\n /** Buttons under the lead. */\n actions?: React.ReactNode;\n specs?: SpecItem[];\n /** An image for the studio frame: a product shot, a screenshot, a portrait. Without it the frame shows a crosshair. */\n image?: React.ReactNode;\n imageLabel?: string;\n /** Replaces the studio frame and grill entirely. */\n media?: React.ReactNode;\n serial?: string;\n coords?: string;\n className?: string;\n};\n\n/** Studio-backdrop frame for the hero image, with an inner ring and a microprint tag. */\nexport function HeroFrame({ image, label }: { image?: React.ReactNode; label?: string }) {\n return (\n <div className=\"relative flex h-60 w-50 items-center justify-center overflow-hidden rounded-md bg-studio [&>img]:size-full [&>img]:object-cover\">\n {image ?? <Crosshair className=\"size-5 text-ink/45\" />}\n <span\n aria-hidden\n className=\"pointer-events-none absolute inset-3.5 rounded-sm shadow-[inset_0_0_0_1px_rgba(255,255,255,0.55)]\"\n />\n {label && <span className=\"hud-sm absolute bottom-2.5 left-2.5 text-ink\">{label}</span>}\n </div>\n );\n}\n\n/** The opening part of a page: title, subtitle, lead, actions and specs beside an image. */\nexport function Hero({\n title,\n subtitle,\n lead,\n actions,\n specs,\n image,\n imageLabel,\n media,\n serial,\n coords,\n className,\n}: HeroProps) {\n return (\n <section className={cn(\"relative drop-float\", className)}>\n <span\n aria-hidden\n className=\"absolute -top-1.5 left-6 z-10 h-3 w-18 rounded-full bg-signal md:left-16\"\n />\n <div className=\"relative grid gap-12 rounded-xl bg-shell notch-lg px-6 pt-12 pb-8 md:grid-cols-[1fr_auto] md:px-16 md:pt-16 md:pb-12\">\n {serial && (\n <span className=\"hud-sm absolute top-6 left-6 text-hud-mark md:left-16\">{serial}</span>\n )}\n <div className=\"flex min-w-0 flex-col gap-6\">\n <h1 className=\"font-display text-display-lg text-ink md:text-display-xl\">{title}</h1>\n {subtitle && <p className=\"hud text-signal-ink\">{subtitle}</p>}\n {lead && <p className=\"max-w-[36em] text-body-lg text-ink-soft\">{lead}</p>}\n {actions && <div className=\"flex flex-wrap items-center gap-3\">{actions}</div>}\n {specs && <SpecReadout items={specs} />}\n </div>\n <div className=\"flex flex-col items-start gap-4 md:items-end\">\n {media ?? (\n <>\n <HeroFrame image={image} label={imageLabel} />\n <Grill count={4} slotWidth={28} gap=\"8px\" />\n </>\n )}\n {coords && <span className=\"hud-sm text-hud-mark\">{coords}</span>}\n </div>\n <Crosshair tone=\"signal\" className=\"absolute right-3.5 bottom-3.5\" />\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;AAyBA,SAAgB,UAAU,EAAE,OAAO,SAAsD;CACvF,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACG,SAAS,oBAAC,WAAD,EAAW,WAAU,qBAAsB,CAAA;GACrD,oBAAC,QAAD;IACE,eAAA;IACA,WAAU;GACX,CAAA;GACA,SAAS,oBAAC,QAAD;IAAM,WAAU;IAAgD,UAAA;GAAY,CAAA;EACnF;;AAET;;AAGA,SAAgB,KAAK,EACnB,OACA,UACA,MACA,SACA,OACA,OACA,YACA,OACA,QACA,QACA,aACY;CACZ,OACE,qBAAC,WAAD;EAAS,WAAW,GAAG,uBAAuB,SAAS;EAAvD,UAAA,CACE,oBAAC,QAAD;GACE,eAAA;GACA,WAAU;EACX,CAAA,GACD,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACG,UACC,oBAAC,QAAD;KAAM,WAAU;KAAyD,UAAA;IAAa,CAAA;IAExF,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,oBAAC,MAAD;OAAI,WAAU;OAA4D,UAAA;MAAU,CAAA;MACnF,YAAY,oBAAC,KAAD;OAAG,WAAU;OAAuB,UAAA;MAAY,CAAA;MAC5D,QAAQ,oBAAC,KAAD;OAAG,WAAU;OAA2C,UAAA;MAAQ,CAAA;MACxE,WAAW,oBAAC,OAAD;OAAK,WAAU;OAAqC,UAAA;MAAa,CAAA;MAC5E,SAAS,oBAAC,aAAD,EAAa,OAAO,MAAQ,CAAA;KACnC;;IACL,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACG,SACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,WAAD;MAAkB;MAAO,OAAO;KAAa,CAAA,GAC7C,oBAAC,OAAD;MAAO,OAAO;MAAG,WAAW;MAAI,KAAI;KAAO,CAAA,CAC3C,EAAA,CAAA,GAEH,UAAU,oBAAC,QAAD;MAAM,WAAU;MAAwB,UAAA;KAAa,CAAA,CAC7D;;IACL,oBAAC,WAAD;KAAW,MAAK;KAAS,WAAU;IAAiC,CAAA;GACjE;EACE,CAAA,CAAA;;AAEb"}
@@ -0,0 +1,41 @@
1
+ import * as React from "react";
2
+ /** 12px plus-mark used as a registration mark on corners and frames. Decorative. */
3
+ export declare function Crosshair({ tone, className, ...props }: React.ComponentProps<"svg"> & {
4
+ tone?: "signal";
5
+ }): React.JSX.Element;
6
+ /** Mono overline: signal code chip, label, a seam rule and an optional end marker. */
7
+ export declare function HudLabel({ code, end, rule, className, children, ...props }: React.ComponentProps<"div"> & {
8
+ code?: string;
9
+ end?: React.ReactNode;
10
+ rule?: boolean;
11
+ }): React.JSX.Element;
12
+ /** Measurement-tape strip: major ticks every 40px, minor every 8px. Decorative. */
13
+ export declare function TickRuler({ labels, className }: {
14
+ labels?: string[];
15
+ className?: string;
16
+ }): React.JSX.Element;
17
+ /** LED dot with a word next to it. Color never carries the meaning alone. */
18
+ export declare function StatusLed({ tone, className, children, ...props }: React.ComponentProps<"span"> & {
19
+ tone?: "on" | "signal" | "off";
20
+ }): React.JSX.Element;
21
+ /** Pegboard slots: the product grill. Decorative. */
22
+ export declare function Grill({ count, slotWidth, gap, tone, className }: {
23
+ count?: number;
24
+ /** Slot width in px. Defaults to 36. */
25
+ slotWidth?: number;
26
+ /** Gap between slots as a CSS length. Defaults to 10px. */
27
+ gap?: string;
28
+ tone?: "signal" | "on-signal";
29
+ className?: string;
30
+ }): React.JSX.Element;
31
+ /** Section heading: HUD label with code above a Michroma title and an optional aside. */
32
+ export declare function SectionHeader({ title, code, label, aside, ruler, as: Tag, className }: {
33
+ title: React.ReactNode;
34
+ code?: string;
35
+ label?: React.ReactNode;
36
+ aside?: React.ReactNode;
37
+ ruler?: boolean;
38
+ as?: "h1" | "h2" | "h3";
39
+ className?: string;
40
+ }): React.JSX.Element;
41
+ //# sourceMappingURL=hud.d.ts.map