@spatika/react 1.0.0 → 1.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 (369) hide show
  1. package/AGENTS.md +71 -0
  2. package/README.md +4 -3
  3. package/dist/composites/AccentRule.d.ts +6 -0
  4. package/dist/composites/AccentRule.d.ts.map +1 -0
  5. package/dist/composites/AccentRule.js +6 -0
  6. package/dist/composites/AvailabilityBadge.d.ts +9 -0
  7. package/dist/composites/AvailabilityBadge.d.ts.map +1 -0
  8. package/dist/composites/AvailabilityBadge.js +9 -0
  9. package/dist/composites/Card.d.ts +7 -1
  10. package/dist/composites/Card.d.ts.map +1 -1
  11. package/dist/composites/Card.js +10 -0
  12. package/dist/composites/CareerCard.d.ts +20 -0
  13. package/dist/composites/CareerCard.d.ts.map +1 -0
  14. package/dist/composites/CareerCard.js +17 -0
  15. package/dist/composites/ChartDataGrid.d.ts +33 -0
  16. package/dist/composites/ChartDataGrid.d.ts.map +1 -0
  17. package/dist/composites/ChartDataGrid.js +77 -0
  18. package/dist/composites/ContactLink.d.ts +15 -0
  19. package/dist/composites/ContactLink.d.ts.map +1 -0
  20. package/dist/composites/ContactLink.js +8 -0
  21. package/dist/composites/CoverHero.d.ts +1 -1
  22. package/dist/composites/CoverHero.d.ts.map +1 -1
  23. package/dist/composites/CoverHero.js +2 -2
  24. package/dist/composites/DisplayHeading.d.ts +9 -0
  25. package/dist/composites/DisplayHeading.d.ts.map +1 -0
  26. package/dist/composites/DisplayHeading.js +6 -0
  27. package/dist/composites/EntityMediaCard.d.ts +1 -1
  28. package/dist/composites/EntityMediaCard.d.ts.map +1 -1
  29. package/dist/composites/EntityMediaCard.js +12 -4
  30. package/dist/composites/EventCalendar.d.ts +35 -0
  31. package/dist/composites/EventCalendar.d.ts.map +1 -0
  32. package/dist/composites/EventCalendar.js +339 -0
  33. package/dist/composites/EventEditor.d.ts +22 -0
  34. package/dist/composites/EventEditor.d.ts.map +1 -0
  35. package/dist/composites/EventEditor.js +86 -0
  36. package/dist/composites/EventTimeline.d.ts +24 -0
  37. package/dist/composites/EventTimeline.d.ts.map +1 -0
  38. package/dist/composites/EventTimeline.js +184 -0
  39. package/dist/composites/FloatChip.d.ts +15 -0
  40. package/dist/composites/FloatChip.d.ts.map +1 -0
  41. package/dist/composites/FloatChip.js +7 -0
  42. package/dist/composites/GradientText.d.ts +11 -0
  43. package/dist/composites/GradientText.d.ts.map +1 -0
  44. package/dist/composites/GradientText.js +6 -0
  45. package/dist/composites/IconTile.d.ts +10 -0
  46. package/dist/composites/IconTile.d.ts.map +1 -0
  47. package/dist/composites/IconTile.js +7 -0
  48. package/dist/composites/MapChart.d.ts +24 -0
  49. package/dist/composites/MapChart.d.ts.map +1 -0
  50. package/dist/composites/MapChart.js +58 -0
  51. package/dist/composites/MetaChip.d.ts +9 -0
  52. package/dist/composites/MetaChip.d.ts.map +1 -0
  53. package/dist/composites/MetaChip.js +6 -0
  54. package/dist/composites/PresenceDot.d.ts +10 -0
  55. package/dist/composites/PresenceDot.d.ts.map +1 -0
  56. package/dist/composites/PresenceDot.js +10 -0
  57. package/dist/composites/ProfileHero.d.ts +6 -4
  58. package/dist/composites/ProfileHero.d.ts.map +1 -1
  59. package/dist/composites/ProfileHero.js +8 -8
  60. package/dist/composites/ProjectCard.d.ts +12 -0
  61. package/dist/composites/ProjectCard.d.ts.map +1 -0
  62. package/dist/composites/ProjectCard.js +9 -0
  63. package/dist/composites/ScatterWebGL.d.ts +22 -0
  64. package/dist/composites/ScatterWebGL.d.ts.map +1 -0
  65. package/dist/composites/ScatterWebGL.js +45 -0
  66. package/dist/composites/SectionHeading.d.ts +16 -0
  67. package/dist/composites/SectionHeading.d.ts.map +1 -0
  68. package/dist/composites/SectionHeading.js +12 -0
  69. package/dist/composites/SiteFooter.d.ts +18 -0
  70. package/dist/composites/SiteFooter.d.ts.map +1 -0
  71. package/dist/composites/SiteFooter.js +15 -0
  72. package/dist/composites/SiteNav.d.ts +25 -0
  73. package/dist/composites/SiteNav.d.ts.map +1 -0
  74. package/dist/composites/SiteNav.js +44 -0
  75. package/dist/composites/StatCard.d.ts +7 -1
  76. package/dist/composites/StatCard.d.ts.map +1 -1
  77. package/dist/composites/StatCard.js +5 -2
  78. package/dist/composites/StatusDot.d.ts +1 -1
  79. package/dist/composites/Tag.d.ts +11 -0
  80. package/dist/composites/Tag.d.ts.map +1 -0
  81. package/dist/composites/Tag.js +33 -0
  82. package/dist/composites/Wordmark.d.ts +19 -0
  83. package/dist/composites/Wordmark.d.ts.map +1 -0
  84. package/dist/composites/Wordmark.js +15 -0
  85. package/dist/composites/cartesian-charts.d.ts +138 -0
  86. package/dist/composites/cartesian-charts.d.ts.map +1 -0
  87. package/dist/composites/cartesian-charts.js +401 -0
  88. package/dist/composites/chart-composition.d.ts +139 -0
  89. package/dist/composites/chart-composition.d.ts.map +1 -0
  90. package/dist/composites/chart-composition.js +486 -0
  91. package/dist/composites/chart-ui.d.ts +83 -0
  92. package/dist/composites/chart-ui.d.ts.map +1 -0
  93. package/dist/composites/chart-ui.js +108 -0
  94. package/dist/composites/charts-3d.d.ts +37 -0
  95. package/dist/composites/charts-3d.d.ts.map +1 -0
  96. package/dist/composites/charts-3d.js +121 -0
  97. package/dist/composites/flow-charts.d.ts +89 -0
  98. package/dist/composites/flow-charts.d.ts.map +1 -0
  99. package/dist/composites/flow-charts.js +186 -0
  100. package/dist/composites/radial-charts.d.ts +109 -0
  101. package/dist/composites/radial-charts.d.ts.map +1 -0
  102. package/dist/composites/radial-charts.js +176 -0
  103. package/dist/composites/scheduler-ui.d.ts +43 -0
  104. package/dist/composites/scheduler-ui.d.ts.map +1 -0
  105. package/dist/composites/scheduler-ui.js +71 -0
  106. package/dist/index.d.ts +83 -7
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +74 -7
  109. package/dist/lib/chart-export.d.ts +10 -0
  110. package/dist/lib/chart-export.d.ts.map +1 -0
  111. package/dist/lib/chart-export.js +102 -0
  112. package/dist/lib/charts.d.ts +235 -0
  113. package/dist/lib/charts.d.ts.map +1 -0
  114. package/dist/lib/charts.js +744 -0
  115. package/dist/lib/geo.d.ts +39 -0
  116. package/dist/lib/geo.d.ts.map +1 -0
  117. package/dist/lib/geo.js +101 -0
  118. package/dist/lib/iso.d.ts +21 -0
  119. package/dist/lib/iso.d.ts.map +1 -0
  120. package/dist/lib/iso.js +56 -0
  121. package/dist/lib/rrule.d.ts +20 -0
  122. package/dist/lib/rrule.d.ts.map +1 -0
  123. package/dist/lib/rrule.js +236 -0
  124. package/dist/lib/scheduler.d.ts +152 -0
  125. package/dist/lib/scheduler.d.ts.map +1 -0
  126. package/dist/lib/scheduler.js +501 -0
  127. package/dist/lib/webgl-scatter.d.ts +44 -0
  128. package/dist/lib/webgl-scatter.d.ts.map +1 -0
  129. package/dist/lib/webgl-scatter.js +185 -0
  130. package/dist/primitives/Accordion.d.ts +44 -20
  131. package/dist/primitives/Accordion.d.ts.map +1 -1
  132. package/dist/primitives/Accordion.js +82 -22
  133. package/dist/primitives/AppBar.d.ts +13 -0
  134. package/dist/primitives/AppBar.d.ts.map +1 -0
  135. package/dist/primitives/AppBar.js +27 -0
  136. package/dist/primitives/Autocomplete.d.ts +28 -0
  137. package/dist/primitives/Autocomplete.d.ts.map +1 -0
  138. package/dist/primitives/Autocomplete.js +118 -0
  139. package/dist/primitives/Avatar.d.ts +13 -1
  140. package/dist/primitives/Avatar.d.ts.map +1 -1
  141. package/dist/primitives/Avatar.js +17 -2
  142. package/dist/primitives/Backdrop.d.ts +17 -0
  143. package/dist/primitives/Backdrop.d.ts.map +1 -0
  144. package/dist/primitives/Backdrop.js +17 -0
  145. package/dist/primitives/BottomNavigation.d.ts +23 -0
  146. package/dist/primitives/BottomNavigation.d.ts.map +1 -0
  147. package/dist/primitives/BottomNavigation.js +30 -0
  148. package/dist/primitives/Button.d.ts +4 -4
  149. package/dist/primitives/Button.d.ts.map +1 -1
  150. package/dist/primitives/Button.js +2 -0
  151. package/dist/primitives/ButtonBase.d.ts +14 -0
  152. package/dist/primitives/ButtonBase.d.ts.map +1 -0
  153. package/dist/primitives/ButtonBase.js +13 -0
  154. package/dist/primitives/ButtonGroup.d.ts +25 -0
  155. package/dist/primitives/ButtonGroup.d.ts.map +1 -0
  156. package/dist/primitives/ButtonGroup.js +44 -0
  157. package/dist/primitives/CircularProgress.d.ts +16 -0
  158. package/dist/primitives/CircularProgress.d.ts.map +1 -0
  159. package/dist/primitives/CircularProgress.js +17 -0
  160. package/dist/primitives/ClickAwayListener.d.ts +16 -0
  161. package/dist/primitives/ClickAwayListener.d.ts.map +1 -0
  162. package/dist/primitives/ClickAwayListener.js +33 -0
  163. package/dist/primitives/Collapse.d.ts +19 -0
  164. package/dist/primitives/Collapse.d.ts.map +1 -0
  165. package/dist/primitives/Collapse.js +14 -0
  166. package/dist/primitives/Container.d.ts +13 -0
  167. package/dist/primitives/Container.d.ts.map +1 -0
  168. package/dist/primitives/Container.js +26 -0
  169. package/dist/primitives/Fab.d.ts +22 -0
  170. package/dist/primitives/Fab.d.ts.map +1 -0
  171. package/dist/primitives/Fab.js +42 -0
  172. package/dist/primitives/FormControl.d.ts +27 -0
  173. package/dist/primitives/FormControl.d.ts.map +1 -0
  174. package/dist/primitives/FormControl.js +24 -0
  175. package/dist/primitives/FormControlLabel.d.ts +18 -0
  176. package/dist/primitives/FormControlLabel.d.ts.map +1 -0
  177. package/dist/primitives/FormControlLabel.js +19 -0
  178. package/dist/primitives/Grid.d.ts +32 -0
  179. package/dist/primitives/Grid.d.ts.map +1 -0
  180. package/dist/primitives/Grid.js +50 -0
  181. package/dist/primitives/IconButton.d.ts +22 -0
  182. package/dist/primitives/IconButton.d.ts.map +1 -0
  183. package/dist/primitives/IconButton.js +39 -0
  184. package/dist/primitives/ImageList.d.ts +31 -0
  185. package/dist/primitives/ImageList.d.ts.map +1 -0
  186. package/dist/primitives/ImageList.js +33 -0
  187. package/dist/primitives/InputAdornment.d.ts +28 -0
  188. package/dist/primitives/InputAdornment.d.ts.map +1 -0
  189. package/dist/primitives/InputAdornment.js +13 -0
  190. package/dist/primitives/Link.d.ts +17 -0
  191. package/dist/primitives/Link.d.ts.map +1 -0
  192. package/dist/primitives/Link.js +29 -0
  193. package/dist/primitives/List.d.ts +41 -0
  194. package/dist/primitives/List.d.ts.map +1 -0
  195. package/dist/primitives/List.js +22 -0
  196. package/dist/primitives/Masonry.d.ts +14 -0
  197. package/dist/primitives/Masonry.d.ts.map +1 -0
  198. package/dist/primitives/Masonry.js +15 -0
  199. package/dist/primitives/Menu.d.ts +28 -0
  200. package/dist/primitives/Menu.d.ts.map +1 -0
  201. package/dist/primitives/Menu.js +54 -0
  202. package/dist/primitives/MobileStepper.d.ts +15 -0
  203. package/dist/primitives/MobileStepper.d.ts.map +1 -0
  204. package/dist/primitives/MobileStepper.js +8 -0
  205. package/dist/primitives/Modal.d.ts +18 -0
  206. package/dist/primitives/Modal.d.ts.map +1 -0
  207. package/dist/primitives/Modal.js +29 -0
  208. package/dist/primitives/NoSsr.d.ts +15 -0
  209. package/dist/primitives/NoSsr.d.ts.map +1 -0
  210. package/dist/primitives/NoSsr.js +19 -0
  211. package/dist/primitives/Paper.d.ts +22 -0
  212. package/dist/primitives/Paper.d.ts.map +1 -0
  213. package/dist/primitives/Paper.js +33 -0
  214. package/dist/primitives/Progress.d.ts +6 -2
  215. package/dist/primitives/Progress.d.ts.map +1 -1
  216. package/dist/primitives/Progress.js +8 -3
  217. package/dist/primitives/Snackbar.d.ts +23 -0
  218. package/dist/primitives/Snackbar.d.ts.map +1 -0
  219. package/dist/primitives/Snackbar.js +33 -0
  220. package/dist/primitives/SpeedDial.d.ts +26 -0
  221. package/dist/primitives/SpeedDial.d.ts.map +1 -0
  222. package/dist/primitives/SpeedDial.js +26 -0
  223. package/dist/primitives/Stack.d.ts +15 -0
  224. package/dist/primitives/Stack.d.ts.map +1 -0
  225. package/dist/primitives/Stack.js +45 -0
  226. package/dist/primitives/StarRating.d.ts +19 -1
  227. package/dist/primitives/StarRating.d.ts.map +1 -1
  228. package/dist/primitives/StarRating.js +36 -6
  229. package/dist/primitives/Stepper.d.ts +36 -0
  230. package/dist/primitives/Stepper.d.ts.map +1 -0
  231. package/dist/primitives/Stepper.js +53 -0
  232. package/dist/primitives/TablePagination.d.ts +16 -0
  233. package/dist/primitives/TablePagination.d.ts.map +1 -0
  234. package/dist/primitives/TablePagination.js +12 -0
  235. package/dist/primitives/TextField.d.ts +24 -0
  236. package/dist/primitives/TextField.d.ts.map +1 -0
  237. package/dist/primitives/TextField.js +19 -0
  238. package/dist/primitives/TextareaAutosize.d.ts +11 -0
  239. package/dist/primitives/TextareaAutosize.d.ts.map +1 -0
  240. package/dist/primitives/TextareaAutosize.js +26 -0
  241. package/dist/primitives/ToggleButton.d.ts +28 -0
  242. package/dist/primitives/ToggleButton.d.ts.map +1 -0
  243. package/dist/primitives/ToggleButton.js +56 -0
  244. package/dist/primitives/TransferList.d.ts +21 -0
  245. package/dist/primitives/TransferList.d.ts.map +1 -0
  246. package/dist/primitives/TransferList.js +40 -0
  247. package/dist/primitives/Typography.d.ts +23 -0
  248. package/dist/primitives/Typography.d.ts.map +1 -0
  249. package/dist/primitives/Typography.js +69 -0
  250. package/dist/primitives/transitions.d.ts +29 -0
  251. package/dist/primitives/transitions.d.ts.map +1 -0
  252. package/dist/primitives/transitions.js +52 -0
  253. package/package.json +30 -5
  254. package/skills/spatika-ui/SKILL.md +96 -0
  255. package/src/composites/AccentRule.tsx +12 -0
  256. package/src/composites/AvailabilityBadge.tsx +32 -0
  257. package/src/composites/Card.tsx +51 -1
  258. package/src/composites/CareerCard.tsx +111 -0
  259. package/src/composites/ChartDataGrid.test.tsx +57 -0
  260. package/src/composites/ChartDataGrid.tsx +196 -0
  261. package/src/composites/ContactLink.tsx +66 -0
  262. package/src/composites/CoverHero.test.tsx +38 -0
  263. package/src/composites/CoverHero.tsx +29 -22
  264. package/src/composites/DisplayHeading.tsx +27 -0
  265. package/src/composites/EntityMediaCard.test.tsx +58 -0
  266. package/src/composites/EntityMediaCard.tsx +31 -13
  267. package/src/composites/EventCalendar.tsx +928 -0
  268. package/src/composites/EventEditor.tsx +268 -0
  269. package/src/composites/EventTimeline.tsx +357 -0
  270. package/src/composites/FloatChip.tsx +63 -0
  271. package/src/composites/GradientText.tsx +31 -0
  272. package/src/composites/IconTile.tsx +33 -0
  273. package/src/composites/MapChart.test.tsx +39 -0
  274. package/src/composites/MapChart.tsx +130 -0
  275. package/src/composites/MetaChip.tsx +24 -0
  276. package/src/composites/PresenceDot.tsx +42 -0
  277. package/src/composites/ProfileHero.test.tsx +33 -0
  278. package/src/composites/ProfileHero.tsx +96 -79
  279. package/src/composites/ProjectCard.tsx +65 -0
  280. package/src/composites/ScatterWebGL.test.tsx +25 -0
  281. package/src/composites/ScatterWebGL.tsx +79 -0
  282. package/src/composites/SectionHeading.tsx +61 -0
  283. package/src/composites/SiteFooter.test.tsx +37 -0
  284. package/src/composites/SiteFooter.tsx +79 -0
  285. package/src/composites/SiteNav.test.tsx +46 -0
  286. package/src/composites/SiteNav.tsx +150 -0
  287. package/src/composites/StatCard.test.tsx +30 -0
  288. package/src/composites/StatCard.tsx +36 -1
  289. package/src/composites/Tag.tsx +50 -0
  290. package/src/composites/Wordmark.test.tsx +23 -0
  291. package/src/composites/Wordmark.tsx +46 -0
  292. package/src/composites/cartesian-charts.test.tsx +52 -0
  293. package/src/composites/cartesian-charts.tsx +1287 -0
  294. package/src/composites/chart-composition.test.tsx +53 -0
  295. package/src/composites/chart-composition.tsx +898 -0
  296. package/src/composites/chart-ui.tsx +328 -0
  297. package/src/composites/charts-3d.test.tsx +25 -0
  298. package/src/composites/charts-3d.tsx +318 -0
  299. package/src/composites/charts.test.tsx +254 -0
  300. package/src/composites/chrome.test.tsx +29 -0
  301. package/src/composites/flow-charts.test.tsx +79 -0
  302. package/src/composites/flow-charts.tsx +607 -0
  303. package/src/composites/marketing.test.tsx +192 -0
  304. package/src/composites/radial-charts.test.tsx +74 -0
  305. package/src/composites/radial-charts.tsx +617 -0
  306. package/src/composites/scheduler-ui.tsx +304 -0
  307. package/src/composites/scheduler.test.tsx +194 -0
  308. package/src/index.test.ts +22 -0
  309. package/src/index.ts +300 -5
  310. package/src/lib/chart-export.test.ts +20 -0
  311. package/src/lib/chart-export.ts +99 -0
  312. package/src/lib/charts-platform.test.ts +93 -0
  313. package/src/lib/charts.test.ts +132 -0
  314. package/src/lib/charts.ts +1021 -0
  315. package/src/lib/geo.test.ts +42 -0
  316. package/src/lib/geo.ts +138 -0
  317. package/src/lib/iso.test.ts +22 -0
  318. package/src/lib/iso.ts +102 -0
  319. package/src/lib/rrule.test.ts +53 -0
  320. package/src/lib/rrule.ts +281 -0
  321. package/src/lib/scheduler.test.ts +186 -0
  322. package/src/lib/scheduler.ts +688 -0
  323. package/src/lib/tokens.test.ts +2 -2
  324. package/src/lib/webgl-scatter.test.ts +36 -0
  325. package/src/lib/webgl-scatter.ts +230 -0
  326. package/src/primitives/Accordion.tsx +218 -63
  327. package/src/primitives/AppBar.tsx +39 -0
  328. package/src/primitives/Autocomplete.tsx +236 -0
  329. package/src/primitives/Avatar.tsx +52 -1
  330. package/src/primitives/Backdrop.tsx +48 -0
  331. package/src/primitives/BottomNavigation.tsx +102 -0
  332. package/src/primitives/Button.tsx +3 -0
  333. package/src/primitives/ButtonBase.tsx +34 -0
  334. package/src/primitives/ButtonGroup.tsx +90 -0
  335. package/src/primitives/CircularProgress.tsx +104 -0
  336. package/src/primitives/ClickAwayListener.tsx +46 -0
  337. package/src/primitives/Collapse.tsx +39 -0
  338. package/src/primitives/Container.tsx +40 -0
  339. package/src/primitives/Fab.tsx +62 -0
  340. package/src/primitives/FormControl.tsx +90 -0
  341. package/src/primitives/FormControlLabel.tsx +51 -0
  342. package/src/primitives/Grid.tsx +101 -0
  343. package/src/primitives/IconButton.tsx +59 -0
  344. package/src/primitives/ImageList.test.tsx +48 -0
  345. package/src/primitives/ImageList.tsx +112 -0
  346. package/src/primitives/InputAdornment.tsx +86 -0
  347. package/src/primitives/Link.tsx +48 -0
  348. package/src/primitives/List.tsx +121 -0
  349. package/src/primitives/Masonry.tsx +32 -0
  350. package/src/primitives/Menu.tsx +112 -0
  351. package/src/primitives/MobileStepper.tsx +64 -0
  352. package/src/primitives/Modal.tsx +70 -0
  353. package/src/primitives/NoSsr.tsx +28 -0
  354. package/src/primitives/Paper.tsx +55 -0
  355. package/src/primitives/Progress.tsx +25 -7
  356. package/src/primitives/Snackbar.tsx +83 -0
  357. package/src/primitives/SpeedDial.tsx +110 -0
  358. package/src/primitives/Stack.tsx +88 -0
  359. package/src/primitives/StarRating.tsx +87 -28
  360. package/src/primitives/Stepper.tsx +184 -0
  361. package/src/primitives/TablePagination.tsx +58 -0
  362. package/src/primitives/TextField.tsx +105 -0
  363. package/src/primitives/TextareaAutosize.tsx +49 -0
  364. package/src/primitives/ToggleButton.tsx +148 -0
  365. package/src/primitives/TransferList.tsx +110 -0
  366. package/src/primitives/Typography.tsx +90 -0
  367. package/src/primitives/mui-more.test.tsx +76 -0
  368. package/src/primitives/mui.test.tsx +134 -0
  369. package/src/primitives/transitions.tsx +120 -0
@@ -0,0 +1,184 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useRef, useState } from "react";
3
+ import { expandVisibleEvents } from "../lib/rrule";
4
+ import { useControllableState } from "../lib/use-controllable-state";
5
+ import { eventCanDrag, eventCanResize, eventColorStyle, formatMonthYear, getTimelineRange, layoutTimelineBars, normalizeEvents, occurrenceKey, resizeEvent, shiftByMs, shiftTimelineDate, toDate, visibleEvents, } from "../lib/scheduler";
6
+ import { EventEditor } from "./EventEditor";
7
+ import { EventResizeHandle, ResourceLegend, SchedulerShell, SchedulerToolbar, TIMELINE_SCALE_LABEL, } from "./scheduler-ui";
8
+ import { DropdownMenuItem } from "../primitives/DropdownMenu";
9
+ const LANE_HEIGHT = 28;
10
+ const LANE_GAP = 4;
11
+ const ROW_PAD = 10;
12
+ function sourceEvent(events, id) {
13
+ return events.find((event) => event.id === id);
14
+ }
15
+ function draftFromSource(source) {
16
+ return {
17
+ id: source.id,
18
+ title: source.title,
19
+ start: toDate(source.start),
20
+ end: toDate(source.end),
21
+ allDay: source.allDay,
22
+ resourceId: source.resourceId,
23
+ color: source.color,
24
+ description: source.description,
25
+ rrule: source.rrule,
26
+ };
27
+ }
28
+ function timelineTitle(scale, date, rangeStart, rangeEnd, locale) {
29
+ if (scale === "hours") {
30
+ return new Intl.DateTimeFormat(locale, { weekday: "short", month: "short", day: "numeric" }).format(date);
31
+ }
32
+ if (scale === "years") {
33
+ return `${rangeStart.getFullYear()}–${rangeEnd.getFullYear() - 1}`;
34
+ }
35
+ if (scale === "months")
36
+ return String(date.getFullYear());
37
+ return formatMonthYear(date, locale);
38
+ }
39
+ /** Horizontal resource timeline — rows are resources, bars are allocations across time. */
40
+ export function EventTimeline({ events = [], resources = [], scale: scaleProp, defaultScale = "months", onScaleChange, date: dateProp, defaultDate, onDateChange, scales = ["hours", "days", "weeks", "months", "years"], locale, readOnly = false, areEventsDraggable, areEventsResizable, onEventClick, onEventChange, onEventCreate, onEventDelete, className, }) {
41
+ const [scale, setScale] = useControllableState({
42
+ prop: scaleProp,
43
+ defaultProp: defaultScale,
44
+ onChange: onScaleChange,
45
+ });
46
+ const [date, setDate] = useControllableState({
47
+ prop: dateProp,
48
+ defaultProp: defaultDate ?? new Date(),
49
+ onChange: onDateChange,
50
+ });
51
+ const [hiddenIds, setHiddenIds] = useState(new Set());
52
+ const [draft, setDraft] = useState(null);
53
+ const dragRef = useRef(null);
54
+ const resolvedScale = scale ?? "months";
55
+ const resolvedDate = date ?? new Date();
56
+ const range = useMemo(() => getTimelineRange(resolvedDate, resolvedScale, locale), [resolvedDate, resolvedScale, locale]);
57
+ const canDrag = !readOnly && (areEventsDraggable ?? Boolean(onEventChange));
58
+ const canResize = !readOnly && (areEventsResizable ?? Boolean(onEventChange));
59
+ const editorLocked = readOnly || Boolean(draft?.id && sourceEvent(events, draft.id)?.readOnly);
60
+ const normalized = useMemo(() => {
61
+ const visible = visibleEvents(normalizeEvents(events, resources), hiddenIds);
62
+ return expandVisibleEvents(visible, range.start, range.end, events);
63
+ }, [events, resources, hiddenIds, range.start, range.end]);
64
+ const visibleResources = resources.filter((resource) => !hiddenIds.has(resource.id));
65
+ const rows = visibleResources.length > 0
66
+ ? visibleResources
67
+ : [{ id: "__all", title: "Events", color: "blue" }];
68
+ const title = timelineTitle(resolvedScale, resolvedDate, range.start, range.end, locale);
69
+ function toggleResource(id) {
70
+ setHiddenIds((prev) => {
71
+ const next = new Set(prev);
72
+ if (next.has(id))
73
+ next.delete(id);
74
+ else
75
+ next.add(id);
76
+ return next;
77
+ });
78
+ }
79
+ function openEvent(event) {
80
+ const source = sourceEvent(events, event.id);
81
+ if (source)
82
+ onEventClick?.(source);
83
+ setDraft(source ? draftFromSource(source) : {
84
+ id: event.id,
85
+ title: event.title,
86
+ start: event.start,
87
+ end: event.end,
88
+ allDay: event.allDay,
89
+ resourceId: event.resourceId,
90
+ color: event.color,
91
+ description: event.description,
92
+ rrule: event.rrule,
93
+ });
94
+ }
95
+ function handlePointerDown(event, pointer) {
96
+ if (!onEventChange || !eventCanDrag(event, { readOnly, enabled: canDrag }))
97
+ return;
98
+ pointer.currentTarget.setPointerCapture?.(pointer.pointerId);
99
+ dragRef.current = { id: event.id, x: pointer.clientX, active: false };
100
+ }
101
+ function handlePointerMove(pointer) {
102
+ const drag = dragRef.current;
103
+ if (!drag)
104
+ return;
105
+ if (Math.abs(pointer.clientX - drag.x) > 6)
106
+ drag.active = true;
107
+ }
108
+ function handlePointerUp(event, pointer) {
109
+ const drag = dragRef.current;
110
+ dragRef.current = null;
111
+ if (!drag?.active || !onEventChange)
112
+ return;
113
+ const grid = pointer.currentTarget.closest("[data-scheduler-grid]");
114
+ if (!grid)
115
+ return;
116
+ const rect = grid.getBoundingClientRect();
117
+ const rangeMs = range.end.getTime() - range.start.getTime();
118
+ const deltaPx = pointer.clientX - drag.x;
119
+ const deltaMs = (deltaPx / rect.width) * rangeMs;
120
+ const source = sourceEvent(events, event.id);
121
+ if (!source)
122
+ return;
123
+ const master = normalizeEvents([source], resources)[0];
124
+ onEventChange(source, shiftByMs(master, deltaMs));
125
+ }
126
+ function commitResize(event, edge, instant) {
127
+ if (!onEventChange)
128
+ return;
129
+ const next = resizeEvent(event, edge, instant);
130
+ const source = sourceEvent(events, event.id);
131
+ if (!source)
132
+ return;
133
+ const master = normalizeEvents([source], resources)[0];
134
+ onEventChange(source, {
135
+ start: new Date(master.start.getTime() + (next.start.getTime() - event.start.getTime())),
136
+ end: new Date(master.end.getTime() + (next.end.getTime() - event.end.getTime())),
137
+ });
138
+ }
139
+ function renderBar(event) {
140
+ const resizable = eventCanResize(event, { readOnly, enabled: canResize }) && Boolean(onEventChange);
141
+ const button = (_jsx("button", { type: "button", className: "flex h-6 w-full items-center truncate rounded-md px-2 text-left text-[11px] font-semibold shadow-sm", style: eventColorStyle(event.color, "bar"), onClick: () => {
142
+ if (dragRef.current?.active)
143
+ return;
144
+ openEvent(event);
145
+ }, onPointerDown: (pointer) => handlePointerDown(event, pointer), onPointerMove: handlePointerMove, onPointerUp: (pointer) => handlePointerUp(event, pointer), children: event.title }));
146
+ if (!resizable)
147
+ return button;
148
+ return (_jsxs("div", { className: "relative h-full", children: [button, _jsx(EventResizeHandle, { event: event, edge: "start", axis: "ew", onCommit: commitResize }), _jsx(EventResizeHandle, { event: event, edge: "end", axis: "ew", onCommit: commitResize })] }));
149
+ }
150
+ return (_jsxs(SchedulerShell, { slot: "event-timeline", className: className, "aria-label": "Event timeline", children: [_jsx(SchedulerToolbar, { title: title, onPrev: () => setDate(shiftTimelineDate(resolvedDate, resolvedScale, -1)), onNext: () => setDate(shiftTimelineDate(resolvedDate, resolvedScale, 1)), onToday: () => setDate(new Date()), menuLabel: TIMELINE_SCALE_LABEL[resolvedScale], menu: scales.map((item) => (_jsx(DropdownMenuItem, { onClick: () => setScale(item), children: TIMELINE_SCALE_LABEL[item] }, item))) }), _jsx("div", { className: "overflow-x-auto", children: _jsx("div", { className: "min-w-[720px]", children: _jsxs("div", { className: "grid", style: { gridTemplateColumns: "11rem minmax(0, 1fr)" }, children: [_jsx("div", { className: "border-b border-r border-border/50 px-3 py-2 text-[10px] font-black uppercase tracking-widest text-muted-foreground", children: "Resource" }), _jsx("div", { className: "grid border-b border-border/50", style: { gridTemplateColumns: `repeat(${range.ticks.length}, minmax(0, 1fr))` }, children: range.ticks.map((tick) => (_jsx("div", { className: "border-l border-border/40 px-2 py-2 text-center text-xs font-bold text-foreground first:border-l-0", children: tick.label }, tick.date.toISOString()))) }), rows.map((resource) => {
151
+ const rowEvents = resource.id === "__all"
152
+ ? normalized
153
+ : normalized.filter((event) => event.resourceId === resource.id);
154
+ const bars = layoutTimelineBars(rowEvents, range.start, range.end);
155
+ const laneCount = Math.max(1, ...bars.map((bar) => bar.lane + 1), 1);
156
+ const height = ROW_PAD * 2 + laneCount * LANE_HEIGHT + (laneCount - 1) * LANE_GAP;
157
+ const tone = resource.color ?? (rowEvents[0]?.color ?? "blue");
158
+ return (_jsxs("div", { className: "contents", children: [_jsxs("div", { className: "flex items-center gap-2 border-b border-r border-border/40 px-3 py-2", style: { minHeight: height }, children: [_jsx("span", { className: "size-2.5 shrink-0 rounded-full", style: eventColorStyle(tone, "dot") }), _jsx("span", { className: "truncate text-sm font-semibold text-foreground", children: resource.title })] }), _jsx("div", { "data-scheduler-grid": true, "data-range-start": range.start.getTime(), "data-range-end": range.end.getTime(), className: "relative border-b border-border/40", style: {
159
+ minHeight: height,
160
+ backgroundImage: `repeating-linear-gradient(90deg, transparent, transparent calc(${100 / range.ticks.length}% - 1px), color-mix(in srgb, var(--border) 40%, transparent) calc(${100 / range.ticks.length}% - 1px), color-mix(in srgb, var(--border) 40%, transparent) ${100 / range.ticks.length}%)`,
161
+ }, children: bars.map((bar) => (_jsx("div", { className: "absolute", style: {
162
+ top: ROW_PAD + bar.lane * (LANE_HEIGHT + LANE_GAP),
163
+ left: `${bar.left}%`,
164
+ width: `${bar.width}%`,
165
+ height: LANE_HEIGHT,
166
+ }, children: renderBar(bar.event) }, occurrenceKey(bar.event)))) })] }, resource.id));
167
+ })] }) }) }), _jsx(ResourceLegend, { resources: resources, hiddenIds: hiddenIds, onToggle: toggleResource }), _jsx(EventEditor, { open: draft != null, onOpenChange: (open) => {
168
+ if (!open)
169
+ setDraft(null);
170
+ }, draft: draft, resources: resources, readOnly: editorLocked, onSave: (event) => {
171
+ if (event.id && sourceEvent(events, event.id)) {
172
+ onEventChange?.(sourceEvent(events, event.id), event);
173
+ }
174
+ else {
175
+ onEventCreate?.(event);
176
+ }
177
+ }, onDelete: onEventDelete
178
+ ? (id) => {
179
+ const source = sourceEvent(events, id);
180
+ if (source)
181
+ onEventDelete(source);
182
+ }
183
+ : undefined })] }));
184
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from "react";
2
+ export type FloatChipProps = {
3
+ icon?: ReactNode;
4
+ title?: ReactNode;
5
+ subtitle?: ReactNode;
6
+ /** Compact live row (green pip + uppercase label) instead of title/subtitle. */
7
+ live?: boolean;
8
+ children?: ReactNode;
9
+ /** CSS float animation. */
10
+ float?: boolean;
11
+ className?: string;
12
+ };
13
+ /** Frosted floating fact chip used around a marketing hero portrait. */
14
+ export declare function FloatChip({ icon, title, subtitle, live, children, float, className, }: FloatChipProps): import("react").JSX.Element;
15
+ //# sourceMappingURL=FloatChip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatChip.d.ts","sourceRoot":"","sources":["../../src/composites/FloatChip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gFAAgF;IAChF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAY,EACZ,QAAQ,EACR,KAAa,EACb,SAAS,GACV,EAAE,cAAc,+BAqChB"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ import { PresenceDot } from "./PresenceDot";
4
+ /** Frosted floating fact chip used around a marketing hero portrait. */
5
+ export function FloatChip({ icon, title, subtitle, live = false, children, float = false, className, }) {
6
+ return (_jsxs("div", { "data-slot": "float-chip", className: cn("inline-flex items-center gap-2.5 rounded-2xl border border-border bg-[color-mix(in_srgb,var(--background)_90%,transparent)] px-3 py-2.5 shadow-[0_12px_32px_rgba(0,0,0,0.12)] backdrop-blur-md", float && "spk-float", className), children: [icon ? (_jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-base", children: icon })) : null, live ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(PresenceDot, { tone: "success" }), _jsx("p", { className: "text-[11px] font-black uppercase leading-none tracking-widest text-[var(--accent-info)]", children: children ?? title })] })) : (_jsxs("div", { children: [title ? (_jsx("p", { className: "text-[12px] font-black uppercase leading-none tracking-wide text-foreground", children: title })) : null, subtitle ? (_jsx("p", { className: "mt-1 text-[10px] font-bold text-muted-foreground", children: subtitle })) : null, children] }))] }));
7
+ }
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from "react";
2
+ export type GradientTextProps = {
3
+ children: ReactNode;
4
+ /** `static` clips a 3-stop theme gradient; `flow` animates it. */
5
+ variant?: "static" | "flow";
6
+ className?: string;
7
+ as?: "span" | "em" | "strong";
8
+ };
9
+ /** Theme-colored gradient type for wordmarks and display names. */
10
+ export declare function GradientText({ children, variant, className, as: Tag, }: GradientTextProps): import("react").JSX.Element;
11
+ //# sourceMappingURL=GradientText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GradientText.d.ts","sourceRoot":"","sources":["../../src/composites/GradientText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,kEAAkE;IAClE,OAAO,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;CAC/B,CAAC;AAEF,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,OAAkB,EAClB,SAAS,EACT,EAAE,EAAE,GAAY,GACjB,EAAE,iBAAiB,+BAanB"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ /** Theme-colored gradient type for wordmarks and display names. */
4
+ export function GradientText({ children, variant = "static", className, as: Tag = "span", }) {
5
+ return (_jsx(Tag, { "data-slot": "gradient-text", "data-variant": variant, className: cn(variant === "flow" ? "spk-gradient-text" : "spk-gradient-text-static", className), children: children }));
6
+ }
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from "react";
2
+ export type IconTileProps = {
3
+ icon: ReactNode;
4
+ title: ReactNode;
5
+ description?: ReactNode;
6
+ className?: string;
7
+ };
8
+ /** Horizontal domain / feature tile: icon well + italic title + caption. */
9
+ export declare function IconTile({ icon, title, description, className }: IconTileProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=IconTile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconTile.d.ts","sourceRoot":"","sources":["../../src/composites/IconTile.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,aAAa,+BAoB9E"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ import { Card } from "./Card";
4
+ /** Horizontal domain / feature tile: icon well + italic title + caption. */
5
+ export function IconTile({ icon, title, description, className }) {
6
+ return (_jsx("div", { "data-slot": "icon-tile", children: _jsxs(Card, { variant: "panel", padding: "md", className: cn("group flex items-center gap-5 p-5", className), children: [_jsx("div", { className: "flex h-14 w-14 shrink-0 items-center justify-center rounded-2xl border border-border bg-secondary text-3xl", children: icon }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-[16px] font-[900] italic text-foreground", children: title }), description ? (_jsx("p", { className: "mt-0.5 text-[12px] font-bold text-muted-foreground", children: description })) : null] })] }) }));
7
+ }
@@ -0,0 +1,24 @@
1
+ import { type ChartMargin } from "../lib/charts";
2
+ import { type GeoJsonFeatureCollection, type GeoProjectionKind } from "../lib/geo";
3
+ export type MapShapeDatum = {
4
+ id: string | number;
5
+ value: number;
6
+ label?: string;
7
+ color?: string;
8
+ };
9
+ export type MapChartProps = {
10
+ geoData: GeoJsonFeatureCollection;
11
+ series?: Array<{
12
+ data: MapShapeDatum[];
13
+ }>;
14
+ idProperty?: string;
15
+ projection?: GeoProjectionKind;
16
+ height?: number;
17
+ width?: number;
18
+ colors?: string[];
19
+ hideLegend?: boolean;
20
+ margin?: ChartMargin;
21
+ className?: string;
22
+ };
23
+ export declare function MapChart({ geoData, series, idProperty, projection, height, width, colors, hideLegend, margin, className, }: MapChartProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=MapChart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapChart.d.ts","sourceRoot":"","sources":["../../src/composites/MapChart.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAIL,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAGpB,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,wBAAwB,CAAC;IAClC,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,MAAM,EACN,UAAiB,EACjB,UAAuB,EACvB,MAAY,EACZ,KAAK,EACL,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE,aAAa,+BA2Ef"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { chartColor, formatChartNumber } from "../lib/charts";
3
+ import { featureId, fitFeatures, geoPath, } from "../lib/geo";
4
+ import { ChartFrame, useChartHover } from "./chart-ui";
5
+ export function MapChart({ geoData, series, idProperty = "id", projection = "mercator", height = 280, width, colors, hideLegend, margin, className, }) {
6
+ const features = geoData.features ?? [];
7
+ const data = series?.[0]?.data ?? [];
8
+ const byId = new Map(data.map((item) => [String(item.id), item]));
9
+ const values = data.map((item) => item.value);
10
+ const min = values.length ? Math.min(...values) : 0;
11
+ const max = values.length ? Math.max(...values) : 1;
12
+ const { hover, setHover, clear } = useChartHover();
13
+ const legend = hideLegend
14
+ ? undefined
15
+ : data.slice(0, 8).map((item, i) => ({
16
+ id: String(item.id),
17
+ label: item.label ?? String(item.id),
18
+ color: item.color ?? choroplethFill(item.value, min, max, i, colors),
19
+ }));
20
+ return (_jsx(ChartFrame, { slot: "map-chart", className: className, width: width, height: height, margin: margin ?? { top: 8, right: 8, bottom: 8, left: 8 }, legend: legend, hover: hover, "aria-label": "Map chart", children: ({ width: w, height: h, m }) => {
21
+ const pad = Math.min(m.left, m.right, m.top, m.bottom);
22
+ const project = fitFeatures(features, w, h, pad, projection);
23
+ return (_jsx("svg", { width: w, height: h, viewBox: `0 0 ${w} ${h}`, children: features.map((feature, i) => {
24
+ if (!feature.geometry)
25
+ return null;
26
+ const id = featureId(feature, idProperty) || String(i);
27
+ const datum = byId.get(id);
28
+ const label = datum?.label ??
29
+ (feature.properties?.name != null ? String(feature.properties.name) : id);
30
+ const fill = datum
31
+ ? (datum.color ?? choroplethFill(datum.value, min, max, i, colors))
32
+ : "color-mix(in srgb, var(--muted) 55%, transparent)";
33
+ const d = geoPath(feature.geometry, project);
34
+ if (!d)
35
+ return null;
36
+ return (_jsx("path", { d: d, fill: fill, className: "spk-chart-map-region spk-chart-mark", onMouseEnter: (event) => setHover({
37
+ x: event.nativeEvent.offsetX,
38
+ y: event.nativeEvent.offsetY,
39
+ title: label,
40
+ items: datum
41
+ ? [
42
+ {
43
+ color: fill,
44
+ label: label,
45
+ value: formatChartNumber(datum.value),
46
+ },
47
+ ]
48
+ : [{ color: fill, label: label, value: "—" }],
49
+ }), onMouseLeave: clear }, id));
50
+ }) }));
51
+ } }));
52
+ }
53
+ function choroplethFill(value, min, max, index, colors) {
54
+ const t = max === min ? 0.6 : (value - min) / (max - min);
55
+ const base = chartColor(index, colors);
56
+ const mix = Math.round(28 + t * 72);
57
+ return `color-mix(in srgb, ${base} ${mix}%, var(--muted))`;
58
+ }
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ export type MetaChipProps = {
3
+ icon?: ReactNode;
4
+ children: ReactNode;
5
+ className?: string;
6
+ };
7
+ /** Compact “powered by” chip: icon + label with a quiet ring. */
8
+ export declare function MetaChip({ icon, children, className }: MetaChipProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=MetaChip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetaChip.d.ts","sourceRoot":"","sources":["../../src/composites/MetaChip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,aAAa,+BAapE"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ /** Compact “powered by” chip: icon + label with a quiet ring. */
4
+ export function MetaChip({ icon, children, className }) {
5
+ return (_jsxs("span", { "data-slot": "meta-chip", className: cn("inline-flex items-center gap-1.5 rounded-lg bg-secondary px-2.5 py-1.5 text-[11px] font-medium text-muted-foreground ring-1 ring-border/80", className), children: [icon ? _jsx("span", { className: "inline-flex h-4 w-4 shrink-0 items-center justify-center opacity-90", children: icon }) : null, children] }));
6
+ }
@@ -0,0 +1,10 @@
1
+ export type PresenceDotProps = {
2
+ tone?: "primary" | "success";
3
+ /** Dual-span scale ping. Defaults to true. */
4
+ ping?: boolean;
5
+ className?: string;
6
+ label?: string;
7
+ };
8
+ /** Live status pip with optional ping halo (availability badges, hero chips). */
9
+ export declare function PresenceDot({ tone, ping, className, label, }: PresenceDotProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=PresenceDot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PresenceDot.d.ts","sourceRoot":"","sources":["../../src/composites/PresenceDot.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAOF,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,EAC1B,IAAgB,EAChB,IAAW,EACX,SAAS,EACT,KAAK,GACN,EAAE,gBAAgB,+BAoBlB"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ const toneClass = {
4
+ primary: "bg-primary",
5
+ success: "bg-[var(--accent-info)]",
6
+ };
7
+ /** Live status pip with optional ping halo (availability badges, hero chips). */
8
+ export function PresenceDot({ tone = "primary", ping = true, className, label, }) {
9
+ return (_jsxs("span", { "data-slot": "presence-dot", role: label ? "img" : undefined, "aria-label": label, className: cn("relative flex h-2 w-2", className), children: [ping ? (_jsx("span", { className: cn("absolute inline-flex h-full w-full animate-ping rounded-full opacity-75", toneClass[tone]), "aria-hidden": true })) : null, _jsx("span", { className: cn("relative inline-flex h-2 w-2 rounded-full", toneClass[tone]) })] }));
10
+ }
@@ -24,11 +24,13 @@ export type ProfileHeroProps = {
24
24
  coverKind?: CoverPatternKind | null;
25
25
  dark?: boolean;
26
26
  warm?: boolean;
27
+ /** When false, keep the cover inside this frame (catalog previews). */
28
+ bleed?: boolean;
27
29
  };
28
30
  /**
29
- * Profile / entity hero: cover bleeds into app chrome, overlapping avatar
30
- * notches the frosted identity plate. Stacked in a narrow column; left-notched
31
- * once the plate is wide enough (container query, not viewport).
31
+ * Profile / entity hero: cover fills the frame, overlapping avatar notches
32
+ * the frosted identity plate. Stacked in a narrow column; left-notched once
33
+ * the plate is wide enough (container query, not viewport).
32
34
  */
33
- export declare function ProfileHero({ name, alias, coverUrl, avatarUrl, hideImages, statusBadges, metaLines, stats, tags, topLeading, topActions, avatarAccessory, onAvatarClick, className, coverClassName, identityClassName, children, coverSeed, coverHue, coverKind, dark, warm, }: ProfileHeroProps): import("react").JSX.Element;
35
+ export declare function ProfileHero({ name, alias, coverUrl, avatarUrl, hideImages, statusBadges, metaLines, stats, tags, topLeading, topActions, avatarAccessory, onAvatarClick, className, coverClassName, identityClassName, children, coverSeed, coverHue, coverKind, dark, warm, bleed, }: ProfileHeroProps): import("react").JSX.Element;
34
36
  //# sourceMappingURL=ProfileHero.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileHero.d.ts","sourceRoot":"","sources":["../../src/composites/ProfileHero.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,KAAK,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,QAAc,EACd,SAAS,EACT,IAAI,EACJ,IAAI,GACL,EAAE,gBAAgB,+BAiGlB"}
1
+ {"version":3,"file":"ProfileHero.d.ts","sourceRoot":"","sources":["../../src/composites/ProfileHero.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,KAAK,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,QAAc,EACd,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAY,GACb,EAAE,gBAAgB,+BA+GlB"}
@@ -5,17 +5,17 @@ import { coverMutedClass, coverPlateClass, coverTitleClass, } from "../lib/cover
5
5
  import { getCoverPattern } from "../lib/cover-pattern";
6
6
  import { CoverPattern } from "./CoverPattern";
7
7
  /**
8
- * Profile / entity hero: cover bleeds into app chrome, overlapping avatar
9
- * notches the frosted identity plate. Stacked in a narrow column; left-notched
10
- * once the plate is wide enough (container query, not viewport).
8
+ * Profile / entity hero: cover fills the frame, overlapping avatar notches
9
+ * the frosted identity plate. Stacked in a narrow column; left-notched once
10
+ * the plate is wide enough (container query, not viewport).
11
11
  */
12
- export function ProfileHero({ name, alias, coverUrl, avatarUrl, hideImages, statusBadges, metaLines, stats, tags, topLeading, topActions, avatarAccessory, onAvatarClick, className, coverClassName, identityClassName, children, coverSeed, coverHue = 210, coverKind, dark, warm, }) {
12
+ export function ProfileHero({ name, alias, coverUrl, avatarUrl, hideImages, statusBadges, metaLines, stats, tags, topLeading, topActions, avatarAccessory, onAvatarClick, className, coverClassName, identityClassName, children, coverSeed, coverHue = 210, coverKind, dark, warm, bleed = true, }) {
13
13
  const initials = getInitials(name);
14
14
  const seed = coverSeed ?? name;
15
15
  const scene = getCoverPattern({ seed, hue: coverHue, dark, warm, kind: coverKind });
16
16
  const ink = scene.headerInk;
17
- return (_jsxs("div", { "data-slot": "profile-hero", className: cn("relative overflow-visible", className), children: [_jsxs("div", { className: cn("relative min-h-[9rem] overflow-hidden sm:min-h-[12rem] lg:min-h-[13rem]", coverClassName), children: [_jsxs("div", { className: "cover-media cover-media--profile sm:rounded-b-[2rem]", "aria-hidden": true, children: [!hideImages && coverUrl ? (_jsx("img", { src: coverUrl, alt: "", className: "absolute inset-0 size-full object-cover" })) : (_jsx(CoverPattern, { seed: seed, hue: coverHue, dark: dark, warm: warm, kind: coverKind })), _jsx("div", { className: "absolute inset-x-0 top-0 h-8 bg-gradient-to-b from-black/[0.04] to-transparent dark:from-black/12" }), _jsx("div", { className: "absolute inset-x-0 bottom-0 h-[22%] bg-gradient-to-t from-black/[0.03] via-transparent to-transparent dark:from-black/10" })] }), _jsxs("div", { className: "relative z-10 flex min-h-[9rem] items-start justify-between gap-2 p-3 sm:min-h-[12rem] sm:p-4 lg:min-h-[13rem]", children: [_jsx("div", { children: topLeading }), topActions ? (_jsx("div", { "data-cover-ink": ink, className: "cover-floating-shell flex items-center gap-1 p-1", children: topActions })) : null] })] }), _jsx("div", { className: "relative z-10 px-3 pb-4 sm:px-4 sm:pb-5 lg:px-8", children: _jsxs("div", { className: cn("profile-identity", identityClassName), children: [_jsx("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-0 rounded-[1.35rem] profile-identity__plate", coverPlateClass(ink)) }), _jsxs("div", { className: "profile-identity__body", children: [_jsxs("button", { type: "button", disabled: !onAvatarClick, onClick: onAvatarClick, "aria-label": name, className: "profile-identity__avatar", children: [_jsx("span", { className: "flex items-center justify-center overflow-hidden rounded-full border-[3px] border-white bg-muted text-lg font-black leading-none text-primary shadow-[0_16px_40px_rgba(0,0,0,0.38)] dark:border-white/30", style: {
18
- width: "var(--profile-avatar-size)",
19
- height: "var(--profile-avatar-size)",
20
- }, children: !hideImages && avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "", className: "size-full object-cover" })) : (initials) }), avatarAccessory] }), _jsxs("div", { className: "profile-identity__copy", children: [_jsxs("div", { className: "profile-identity__heading", children: [_jsx("h1", { className: cn("truncate text-[1.15rem] font-black leading-tight tracking-tight sm:text-2xl", coverTitleClass(ink)), children: name }), statusBadges] }), alias ? (_jsx("p", { className: cn("mt-0.5 truncate text-sm font-medium", coverMutedClass(ink)), children: alias })) : null, metaLines ? (_jsx("div", { className: cn("mt-2 space-y-1 text-sm", coverMutedClass(ink)), children: metaLines })) : null, stats ? _jsx("div", { className: "mt-3", children: stats }) : null, tags ? _jsx("div", { className: "profile-identity__tags", children: tags }) : null] })] }), children ? _jsx("div", { className: "relative z-10 px-3 pb-3 sm:px-6", children: children }) : null] }) })] }));
17
+ return (_jsxs("div", { "data-slot": "profile-hero", "data-cover-bleed": bleed ? "true" : undefined, className: cn("relative w-full", bleed ? "overflow-visible" : "overflow-hidden rounded-[1.35rem] sm:rounded-[1.75rem]", className), children: [_jsxs("div", { className: cn("cover-media cover-media--profile", bleed && "sm:rounded-b-[2rem]"), "aria-hidden": true, children: [!hideImages && coverUrl ? (_jsx("img", { src: coverUrl, alt: "", className: "absolute inset-0 size-full object-cover" })) : (_jsx(CoverPattern, { seed: seed, hue: coverHue, dark: dark, warm: warm, kind: coverKind })), _jsx("div", { className: "absolute inset-x-0 top-0 h-8 bg-gradient-to-b from-black/[0.04] to-transparent dark:from-black/12" }), _jsx("div", { className: "absolute inset-x-0 bottom-0 h-[22%] bg-gradient-to-t from-black/[0.03] via-transparent to-transparent dark:from-black/10" })] }), _jsxs("div", { className: "relative z-10 flex flex-col", children: [_jsx("div", { className: cn("relative min-h-[8.5rem] sm:min-h-[11rem] lg:min-h-[12rem]", coverClassName), children: _jsxs("div", { className: "absolute inset-x-0 top-0 z-30 flex items-start justify-between gap-2 p-3 sm:p-4", children: [_jsx("div", { children: topLeading }), topActions ? (_jsx("div", { "data-cover-ink": ink, className: "cover-floating-shell flex items-center gap-1 p-1", children: topActions })) : null] }) }), _jsx("div", { className: "relative z-20 px-3 pb-4 sm:px-4 sm:pb-5 lg:px-6", children: _jsxs("div", { className: cn("profile-identity", identityClassName), children: [_jsx("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-0 rounded-[1.35rem] profile-identity__plate", coverPlateClass(ink)) }), _jsxs("div", { className: "profile-identity__body", children: [_jsxs("button", { type: "button", disabled: !onAvatarClick, onClick: onAvatarClick, "aria-label": name, className: "profile-identity__avatar", children: [_jsx("span", { className: "flex items-center justify-center overflow-hidden rounded-full border-[3px] border-white bg-muted text-lg font-black leading-none text-primary shadow-[0_16px_40px_rgba(0,0,0,0.38)] dark:border-white/30", style: {
18
+ width: "var(--profile-avatar-size)",
19
+ height: "var(--profile-avatar-size)",
20
+ }, children: !hideImages && avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "", className: "size-full object-cover" })) : (initials) }), avatarAccessory] }), _jsxs("div", { className: "profile-identity__copy", children: [_jsxs("div", { className: "profile-identity__heading", children: [_jsx("h1", { className: cn("truncate text-[1.15rem] font-black leading-tight tracking-tight sm:text-2xl", coverTitleClass(ink)), children: name }), statusBadges] }), alias ? (_jsx("p", { className: cn("mt-0.5 truncate text-sm font-medium", coverMutedClass(ink)), children: alias })) : null, metaLines ? (_jsx("div", { className: cn("mt-2 space-y-1 text-sm", coverMutedClass(ink)), children: metaLines })) : null, stats ? _jsx("div", { className: "mt-3", children: stats }) : null, tags ? _jsx("div", { className: "profile-identity__tags", children: tags }) : null] })] }), children ? _jsx("div", { className: "relative z-10 px-3 pb-3 sm:px-6", children: children }) : null] }) })] })] }));
21
21
  }
@@ -0,0 +1,12 @@
1
+ import type { ReactNode } from "react";
2
+ export type ProjectCardProps = {
3
+ title: ReactNode;
4
+ company?: ReactNode;
5
+ outcome?: ReactNode;
6
+ description?: ReactNode;
7
+ tags?: string[];
8
+ className?: string;
9
+ };
10
+ /** Marketing project tile: title, company, outcome pill, body, tech tags. */
11
+ export declare function ProjectCard({ title, company, outcome, description, tags, className, }: ProjectCardProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=ProjectCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectCard.d.ts","sourceRoot":"","sources":["../../src/composites/ProjectCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAO,EACP,OAAO,EACP,WAAW,EACX,IAAS,EACT,SAAS,GACV,EAAE,gBAAgB,+BAyClB"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ import { Badge } from "../primitives/Badge";
4
+ import { Card, CardContent, CardHeader, CardTitle } from "./Card";
5
+ import { Tag } from "./Tag";
6
+ /** Marketing project tile: title, company, outcome pill, body, tech tags. */
7
+ export function ProjectCard({ title, company, outcome, description, tags = [], className, }) {
8
+ return (_jsxs(Card, { variant: "panel", padding: "md", className: cn("group flex h-full flex-col hover:border-primary/30 hover:shadow-[0_12px_32px_color-mix(in_srgb,var(--primary)_7%,transparent)]", className), children: [_jsxs(CardHeader, { className: "mb-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx(CardTitle, { className: "text-[15px] leading-snug font-[900] group-hover:text-primary sm:text-[16px]", children: title }), company ? (_jsx("p", { className: "mt-0.5 text-[11px] font-bold tracking-wider text-muted-foreground uppercase", children: company })) : null] }), outcome ? (_jsx(Badge, { variant: "warm", className: "rounded-full px-2.5 py-1 text-[10px] font-black", children: outcome })) : null] }), _jsxs(CardContent, { className: "flex flex-1 flex-col", children: [description ? (_jsx("p", { className: "mb-3 flex-1 text-[13px] leading-relaxed text-muted-foreground", children: description })) : null, tags.length > 0 ? (_jsx("div", { className: "flex flex-wrap gap-1.5", children: tags.map((tag) => (_jsx(Tag, { children: tag }, tag))) })) : null] })] }));
9
+ }
@@ -0,0 +1,22 @@
1
+ import type { ChartLegendItem } from "./chart-ui";
2
+ type ScatterSeriesLike = {
3
+ data: Array<{
4
+ x: number;
5
+ y: number;
6
+ z?: number;
7
+ }>;
8
+ };
9
+ export declare function ScatterWebGLLayer({ width, height, series, meta, hidden, xAt, yAt, sizeAt, bubble, onUnavailable, }: {
10
+ width: number;
11
+ height: number;
12
+ series: ScatterSeriesLike[];
13
+ meta: ChartLegendItem[];
14
+ hidden: Set<string>;
15
+ xAt: (value: number) => number;
16
+ yAt: (value: number) => number;
17
+ sizeAt: (z: number) => number;
18
+ bubble: boolean;
19
+ onUnavailable?: () => void;
20
+ }): import("react").JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=ScatterWebGL.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScatterWebGL.d.ts","sourceRoot":"","sources":["../../src/composites/ScatterWebGL.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,EACN,GAAG,EACH,GAAG,EACH,MAAM,EACN,MAAM,EACN,aAAa,GACd,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B,+BAgDA"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from "react";
3
+ import { createScatterGL, destroyScatterGL, drawScatterGL } from "../lib/webgl-scatter";
4
+ export function ScatterWebGLLayer({ width, height, series, meta, hidden, xAt, yAt, sizeAt, bubble, onUnavailable, }) {
5
+ const canvasRef = useRef(null);
6
+ const gpuRef = useRef(null);
7
+ useEffect(() => {
8
+ const canvas = canvasRef.current;
9
+ if (!canvas)
10
+ return;
11
+ const gpu = createScatterGL(canvas);
12
+ if (!gpu) {
13
+ onUnavailable?.();
14
+ return;
15
+ }
16
+ gpuRef.current = gpu;
17
+ return () => {
18
+ destroyScatterGL(gpu);
19
+ gpuRef.current = null;
20
+ };
21
+ }, [onUnavailable]);
22
+ useEffect(() => {
23
+ const gpu = gpuRef.current;
24
+ const canvas = canvasRef.current;
25
+ if (!gpu || !canvas)
26
+ return;
27
+ const batches = series.flatMap((item, s) => {
28
+ const info = meta[s];
29
+ if (hidden.has(info.id))
30
+ return [];
31
+ return [
32
+ {
33
+ color: info.color,
34
+ positions: item.data.map((point) => ({
35
+ x: xAt(point.x),
36
+ y: yAt(point.y),
37
+ size: bubble ? sizeAt(point.z ?? 1) * 2 : 9,
38
+ })),
39
+ },
40
+ ];
41
+ });
42
+ drawScatterGL(gpu, canvas, width, height, batches);
43
+ });
44
+ return (_jsx("canvas", { ref: canvasRef, className: "spk-chart-webgl", "data-slot": "scatter-webgl", "aria-hidden": true }));
45
+ }
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+ export type SectionHeadingProps = {
3
+ eyebrow?: ReactNode;
4
+ title: ReactNode;
5
+ subtitle?: ReactNode;
6
+ align?: "left" | "center";
7
+ className?: string;
8
+ /** Hide the accent rule under the copy. */
9
+ showRule?: boolean;
10
+ };
11
+ /**
12
+ * Marketing / page-section title: optional eyebrow, heading, subtitle, and accent rule.
13
+ * Renders a `div` (not `<header>`) so it never competes with the site navbar.
14
+ */
15
+ export declare function SectionHeading({ eyebrow, title, subtitle, align, className, showRule, }: SectionHeadingProps): import("react").JSX.Element;
16
+ //# sourceMappingURL=SectionHeading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionHeading.d.ts","sourceRoot":"","sources":["../../src/composites/SectionHeading.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,KAAK,EACL,QAAQ,EACR,KAAc,EACd,SAAS,EACT,QAAe,GAChB,EAAE,mBAAmB,+BAkCrB"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ import { AccentRule } from "./AccentRule";
4
+ import { GradientText } from "./GradientText";
5
+ /**
6
+ * Marketing / page-section title: optional eyebrow, heading, subtitle, and accent rule.
7
+ * Renders a `div` (not `<header>`) so it never competes with the site navbar.
8
+ */
9
+ export function SectionHeading({ eyebrow, title, subtitle, align = "left", className, showRule = true, }) {
10
+ const centered = align === "center";
11
+ return (_jsxs("div", { "data-slot": "section-heading", className: cn("mb-8 sm:mb-10", centered && "text-center", className), children: [eyebrow ? (_jsx("p", { className: cn("mb-2 text-[11px] font-bold uppercase tracking-[0.14em]", centered && "text-center"), children: _jsx(GradientText, { children: eyebrow }) })) : null, _jsx("h2", { className: "text-[clamp(1.6rem,3.6vw,2.1rem)] font-[800] leading-[1.12] tracking-tight text-foreground", children: title }), subtitle ? (_jsx("p", { className: cn("mt-2 text-[14px] leading-relaxed text-muted-foreground", centered ? "mx-auto max-w-xl" : "max-w-lg"), children: subtitle })) : null, showRule ? _jsx(AccentRule, { className: cn("mt-4", centered && "mx-auto") }) : null] }));
12
+ }