@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
package/AGENTS.md ADDED
@@ -0,0 +1,71 @@
1
+ # Spatika UI — agent guide
2
+
3
+ Glass React design system. Packages: `@spatika/tokens`, `@spatika/react`.
4
+ Human docs: https://spatika.sreelal.me · Machine index: https://spatika.sreelal.me/llms.txt
5
+
6
+ ## Use this library
7
+
8
+ ```bash
9
+ npm install @spatika/tokens @spatika/react
10
+ ```
11
+
12
+ ```tsx
13
+ import "@spatika/tokens/styles.css";
14
+ import { SpatikaThemeProvider, Button } from "@spatika/react";
15
+
16
+ export function App() {
17
+ return (
18
+ <SpatikaThemeProvider defaultTheme="neelam">
19
+ <Button>Hello Spatika</Button>
20
+ </SpatikaThemeProvider>
21
+ );
22
+ }
23
+ ```
24
+
25
+ ### Must do
26
+ - Import `@spatika/tokens/styles.css` before any component
27
+ - Wrap the app in `<SpatikaThemeProvider>`
28
+ - Import from `@spatika/react` — never invent Spatika components
29
+ - Prefer composites (`PageShell`, `FloatingPageChromeBar`, `GlassCard`) over restyling primitives
30
+ - Use token CSS variables, never hardcoded hex
31
+ - Use `size="touch"` for mobile primary actions
32
+ - Animate transform / shadow / color only — never `transition-all` on glass
33
+
34
+ ### Themes
35
+ `mukta` (pearl light) · `neelam` (sapphire dark) · `usha` (dawn) · `sandhya` (dusk, no blur)
36
+
37
+ ### When to use
38
+
39
+ | Need | Component |
40
+ |---|---|
41
+ | App page frame | `PageShell` |
42
+ | List / directory chrome | `FloatingPageChromeBar` |
43
+ | Fixed safe-area bar | `AppHeader variant="chrome"` |
44
+ | Mobile tabs | `MobileTabBar` |
45
+ | Profile / story header | `CoverHero` / `ProfileHero` + `useCoverChromeBleed` |
46
+ | Glass surface | `GlassCard` |
47
+ | Labeled field | `TextField` |
48
+ | Filters | `FilterSheet` + `ChipGroup` |
49
+ | Empty list | `EmptyState` |
50
+ | Titled modal | `Dialog` (not `Modal`) |
51
+ | Toast stack | `Toaster` + `useToast` |
52
+ | Charts | `BarChart`, `LineChart`, or `ChartContainer` |
53
+ | Calendar | `EventCalendar` |
54
+
55
+ Canonical snippets: https://spatika.sreelal.me/docs/components.md
56
+ Prop types: `node_modules/@spatika/react/dist/index.d.ts`
57
+
58
+ Cursor skill (copy into the consumer repo):
59
+ `node_modules/@spatika/react/skills/spatika-ui/` → `.cursor/skills/spatika-ui/`
60
+
61
+ ## Change this library
62
+
63
+ Monorepo: `packages/tokens` (CSS) → `packages/react` (components) → `apps/website` (docs).
64
+
65
+ When adding a component:
66
+ 1. Export it from `packages/react/src/index.ts`
67
+ 2. Add a catalog row in `apps/website/src/data/navigation.ts`
68
+ 3. Add a live demo in `apps/website/src/demos/`
69
+ 4. Add a canonical snippet in `apps/website/src/data/agent-snippets.ts`
70
+
71
+ Run `npm test` and `npm run typecheck` before opening a PR.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @spatika/react
2
2
 
3
- React primitives and composites for Spatika — glass surfaces, four themes, and shared tokens.
3
+ React primitives and composites for **Spatika UI** a glass React design system with four themes and shared tokens.
4
4
 
5
5
  ## Install
6
6
 
@@ -45,8 +45,9 @@ Button sizes include `touch` / `icon-touch` (≥44px) for mobile-first chrome.
45
45
 
46
46
  ## What's included
47
47
 
48
- - **Primitives** — Button, Input, Select, Tabs, Table, Dialog, AlertDialog, Sheet, Popover, DropdownMenu, Command, Tooltip, and more
49
- - **Composites** — AppHeader, AppSidebar, Card, EntityCard, FloatingPageChrome, CoverHero, FilterSheet, MobileTabBar, CommandSearchField, NotificationBell, Timeline, AmountInput, SegmentedControl, Toaster, media cards, PIN/lock chrome
48
+ - **Primitives** — Button, ButtonGroup, Accordion, Autocomplete, Grid, Menu, Dialog, Stepper, List, Fab, and more
49
+ - **Composites** — AppHeader, AppSidebar, Card, EntityCard, FloatingPageChrome, CoverHero, FilterSheet, MobileTabBar, CommandSearchField, NotificationBell, Timeline, EventCalendar, EventTimeline, AmountInput, SegmentedControl, Toaster, media cards, PIN/lock chrome, SiteNav, SiteFooter, SectionHeading, Tag
50
+ - **Charts** — SVG charts covering the MUI X catalog, plus `ChartContainer` composition (mixed plots, zoom/pan, brush, dual axes, toolbar export)
50
51
 
51
52
  ## Tailwind tip
52
53
 
@@ -0,0 +1,6 @@
1
+ export type AccentRuleProps = {
2
+ className?: string;
3
+ };
4
+ /** Short 4px marketing accent bar used under section titles. */
5
+ export declare function AccentRule({ className }: AccentRuleProps): import("react").JSX.Element;
6
+ //# sourceMappingURL=AccentRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccentRule.d.ts","sourceRoot":"","sources":["../../src/composites/AccentRule.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,EAAE,eAAe,+BAIxD"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ /** Short 4px marketing accent bar used under section titles. */
4
+ export function AccentRule({ className }) {
5
+ return (_jsx("div", { "data-slot": "accent-rule", className: cn("spk-hr-accent", className), role: "presentation" }));
6
+ }
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ export type AvailabilityBadgeProps = {
3
+ children: ReactNode;
4
+ tone?: "primary" | "success";
5
+ className?: string;
6
+ };
7
+ /** Pill badge with a live pip — “available for work” treatment. */
8
+ export declare function AvailabilityBadge({ children, tone, className, }: AvailabilityBadgeProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=AvailabilityBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvailabilityBadge.d.ts","sourceRoot":"","sources":["../../src/composites/AvailabilityBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,IAAgB,EAChB,SAAS,GACV,EAAE,sBAAsB,+BAgBxB"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ import { PresenceDot } from "./PresenceDot";
4
+ /** Pill badge with a live pip — “available for work” treatment. */
5
+ export function AvailabilityBadge({ children, tone = "primary", className, }) {
6
+ return (_jsxs("span", { "data-slot": "availability-badge", className: cn("inline-flex items-center gap-2.5 rounded-full border px-4 py-2 text-[12px] font-extrabold uppercase tracking-[0.15em] shadow-sm", tone === "success"
7
+ ? "border-[color-mix(in_srgb,var(--accent-info)_22%,transparent)] bg-[var(--accent-info-bg)] text-[var(--accent-info)]"
8
+ : "border-primary/20 bg-primary/10 text-primary", className), children: [_jsx(PresenceDot, { tone: tone }), children] }));
9
+ }
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import type { ComponentPropsWithoutRef, ReactNode } from "react";
2
2
  export type CardProps = {
3
3
  children: ReactNode;
4
4
  className?: string;
@@ -24,6 +24,12 @@ export declare function CardContent({ className, children, }: {
24
24
  className?: string;
25
25
  children: ReactNode;
26
26
  }): import("react").JSX.Element;
27
+ export declare function CardActionArea({ className, children, ...props }: ComponentPropsWithoutRef<"button">): import("react").JSX.Element;
28
+ export declare function CardMedia({ className, component, image, src, alt, height, ...props }: ComponentPropsWithoutRef<"img"> & {
29
+ component?: "img" | "div";
30
+ image?: string;
31
+ height?: number;
32
+ }): import("react").JSX.Element;
27
33
  export declare function CardFooter({ className, children, }: {
28
34
  className?: string;
29
35
  children: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/composites/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CACvC,CAAC;AAgBF,mFAAmF;AACnF,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,SAAS,EACT,OAAiB,EACjB,OAAc,GACf,EAAE,SAAS,+BAcX;AAED,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BASA"}
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/composites/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGjE,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CACvC,CAAC;AAgBF,mFAAmF;AACnF,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,SAAS,EACT,OAAiB,EACjB,OAAc,GACf,EAAE,SAAS,+BAcX;AAED,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAMA;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,wBAAwB,CAAC,QAAQ,CAAC,+BAepC;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,SAAiB,EACjB,KAAK,EACL,GAAG,EACH,GAAG,EACH,MAAY,EACZ,GAAG,KAAK,EACT,EAAE,wBAAwB,CAAC,KAAK,CAAC,GAAG;IACnC,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,+BAeA;AAED,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BASA"}
@@ -28,6 +28,16 @@ export function CardDescription({ className, children, }) {
28
28
  export function CardContent({ className, children, }) {
29
29
  return (_jsx("div", { "data-slot": "card-content", className: cn(className), children: children }));
30
30
  }
31
+ export function CardActionArea({ className, children, ...props }) {
32
+ return (_jsx("button", { type: "button", "data-slot": "card-action-area", className: cn("block w-full text-left outline-none transition-[transform,box-shadow] duration-150", "hover:-translate-y-0.5 focus-visible:ring-ring/50 focus-visible:ring-[3px]", className), ...props, children: children }));
33
+ }
34
+ export function CardMedia({ className, component = "img", image, src, alt, height = 160, ...props }) {
35
+ const Comp = component;
36
+ return (_jsx(Comp, { "data-slot": "card-media", src: component === "img" ? (src ?? image) : undefined, alt: alt, className: cn("w-full object-cover", component === "div" && "bg-muted", className), style: {
37
+ height,
38
+ ...(component === "div" && image ? { backgroundImage: `url(${image})`, backgroundSize: "cover" } : undefined),
39
+ }, ...props }));
40
+ }
31
41
  export function CardFooter({ className, children, }) {
32
42
  return (_jsx("div", { "data-slot": "card-footer", className: cn("mt-4 flex flex-wrap items-center justify-end gap-2 border-t border-border/40 pt-3", className), children: children }));
33
43
  }
@@ -0,0 +1,20 @@
1
+ import type { ReactNode } from "react";
2
+ export type CareerCardProps = {
3
+ role: ReactNode;
4
+ company: ReactNode;
5
+ location?: ReactNode;
6
+ period?: ReactNode;
7
+ current?: boolean;
8
+ bullets?: ReactNode[];
9
+ tags?: string[];
10
+ className?: string;
11
+ };
12
+ export type CareerTimelineProps = {
13
+ children: ReactNode;
14
+ className?: string;
15
+ };
16
+ /** Vertical career rail with a hairline and slot for CareerCard rows. */
17
+ export declare function CareerTimeline({ children, className }: CareerTimelineProps): import("react").JSX.Element;
18
+ /** Resume / experience card: role, company, period pill, bullets, tech tags. */
19
+ export declare function CareerCard({ role, company, location, period, current, bullets, tags, className, }: CareerCardProps): import("react").JSX.Element;
20
+ //# sourceMappingURL=CareerCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CareerCard.d.ts","sourceRoot":"","sources":["../../src/composites/CareerCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,mBAAmB,+BAO1E;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,MAAM,EACN,OAAe,EACf,OAAY,EACZ,IAAS,EACT,SAAS,GACV,EAAE,eAAe,+BAoEjB"}
@@ -0,0 +1,17 @@
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 } from "./Card";
5
+ import { Tag } from "./Tag";
6
+ /** Vertical career rail with a hairline and slot for CareerCard rows. */
7
+ export function CareerTimeline({ children, className }) {
8
+ return (_jsxs("div", { "data-slot": "career-timeline", className: cn("relative", className), children: [_jsx("div", { className: "absolute top-2 bottom-2 left-[5px] hidden w-px bg-border sm:block", "aria-hidden": true }), _jsx("div", { className: "space-y-3", children: children })] }));
9
+ }
10
+ /** Resume / experience card: role, company, period pill, bullets, tech tags. */
11
+ export function CareerCard({ role, company, location, period, current = false, bullets = [], tags = [], className, }) {
12
+ return (_jsxs("article", { "data-slot": "career-card", className: cn("relative sm:pl-8", className), children: [_jsx("div", { className: cn("absolute top-4 left-0 hidden h-2.5 w-2.5 rounded-full border-2 sm:block", current ? "border-primary bg-primary" : "border-border bg-background"), "aria-hidden": true }), _jsxs(Card, { variant: "panel", padding: "md", className: current
13
+ ? "border-primary/25 bg-gradient-to-br from-[var(--background)] to-primary/[0.04] shadow-[0_8px_28px_color-mix(in_srgb,var(--primary)_7%,transparent)]"
14
+ : "hover:border-primary/20", children: [_jsxs("div", { className: "mb-2.5 flex flex-wrap items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "text-[15px] font-[900] leading-snug text-foreground sm:text-[16px]", children: role }), _jsxs("p", { className: "mt-0.5 text-[13px] font-bold text-primary", children: [company, location ? (_jsxs("span", { className: "font-semibold text-muted-foreground", children: [" \u00B7 ", location] })) : null] })] }), period ? (_jsxs(Badge, { variant: current ? "default" : "secondary", className: current
15
+ ? "rounded-full border-primary bg-primary px-2.5 py-1 text-[11px] font-black text-primary-foreground"
16
+ : "rounded-full px-2.5 py-1 text-[11px] font-black text-muted-foreground", children: [current ? _jsx("span", { className: "h-1.5 w-1.5 animate-pulse rounded-full bg-primary-foreground" }) : null, period] })) : null] }), bullets.length > 0 ? (_jsx("ul", { className: "mb-3 space-y-1.5", children: bullets.map((bullet, index) => (_jsxs("li", { className: "flex gap-2 text-[13px] leading-relaxed text-muted-foreground", children: [_jsx("span", { className: "mt-[7px] h-1 w-1 shrink-0 rounded-full bg-primary/50" }), bullet] }, index))) })) : null, tags.length > 0 ? (_jsx("div", { className: "flex flex-wrap gap-1.5", children: tags.map((tag) => (_jsx(Tag, { children: tag }, tag))) })) : null] })] }));
17
+ }
@@ -0,0 +1,33 @@
1
+ import { type ReactNode } from "react";
2
+ export type ChartGridColumnType = "text" | "number" | "sparkline" | "bar";
3
+ export type ChartGridColumn = {
4
+ field: string;
5
+ headerName: string;
6
+ type?: ChartGridColumnType;
7
+ width?: number;
8
+ };
9
+ export type ChartDataGridRow = {
10
+ id: string;
11
+ } & Record<string, unknown>;
12
+ export type ChartDataGridProps = {
13
+ rows: ChartDataGridRow[];
14
+ columns: ChartGridColumn[];
15
+ chartType?: "bar" | "line" | "pie";
16
+ categoryField: string;
17
+ valueField: string;
18
+ height?: number;
19
+ className?: string;
20
+ selectedIds?: string[];
21
+ defaultSelectedIds?: string[];
22
+ onSelectionChange?: (ids: string[]) => void;
23
+ hideChart?: boolean;
24
+ hideLegend?: boolean;
25
+ };
26
+ export declare function renderChartCell(value: unknown, options?: {
27
+ variant?: "sparkline" | "bar";
28
+ color?: string;
29
+ height?: number;
30
+ max?: number;
31
+ }): ReactNode;
32
+ export declare function ChartDataGrid({ rows, columns, chartType, categoryField, valueField, height, className, selectedIds, defaultSelectedIds, onSelectionChange, hideChart, hideLegend, }: ChartDataGridProps): import("react").JSX.Element;
33
+ //# sourceMappingURL=ChartDataGrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartDataGrid.d.ts","sourceRoot":"","sources":["../../src/composites/ChartDataGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAejD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAExE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,SAAS,CAuBX;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,OAAO,EACP,SAAiB,EACjB,aAAa,EACb,UAAU,EACV,MAAY,EACZ,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,UAAiB,GAClB,EAAE,kBAAkB,+BA4GpB"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { chartColor, formatChartNumber } from "../lib/charts";
4
+ import { cn } from "../lib/cn";
5
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../primitives/Table";
6
+ import { ChartContainer } from "./chart-composition";
7
+ import { SparkLineChart } from "./cartesian-charts";
8
+ import { PieChart } from "./radial-charts";
9
+ export function renderChartCell(value, options) {
10
+ const color = options?.color ?? "var(--chart-1)";
11
+ if (Array.isArray(value) && value.every((item) => typeof item === "number")) {
12
+ return (_jsx(SparkLineChart, { data: value, plotType: options?.variant === "bar" ? "bar" : "line", color: color, height: options?.height ?? 32, showHighlight: false, area: options?.variant !== "bar" }));
13
+ }
14
+ const n = typeof value === "number" ? value : Number(value);
15
+ if (!Number.isFinite(n))
16
+ return "—";
17
+ const max = options?.max && options.max > 0 ? options.max : Math.max(n, 1);
18
+ const pct = Math.max(0, Math.min(100, (n / max) * 100));
19
+ return (_jsx("div", { className: "spk-chart-cell-bar", title: formatChartNumber(n), children: _jsx("span", { style: { width: `${pct}%`, background: color } }) }));
20
+ }
21
+ export function ChartDataGrid({ rows, columns, chartType = "bar", categoryField, valueField, height = 200, className, selectedIds, defaultSelectedIds, onSelectionChange, hideChart, hideLegend = true, }) {
22
+ const [internal, setInternal] = useState(defaultSelectedIds ?? []);
23
+ const selected = selectedIds ?? internal;
24
+ const setSelected = (ids) => {
25
+ if (selectedIds == null)
26
+ setInternal(ids);
27
+ onSelectionChange?.(ids);
28
+ };
29
+ const selectedIndex = selected.length ? rows.findIndex((row) => row.id === selected[0]) : -1;
30
+ const categories = rows.map((row) => String(row[categoryField] ?? row.id));
31
+ const values = rows.map((row) => Number(row[valueField] ?? 0));
32
+ const maxByField = new Map();
33
+ for (const col of columns) {
34
+ if (col.type === "bar" || col.type === "number") {
35
+ const nums = rows.map((row) => Number(row[col.field] ?? 0)).filter((n) => Number.isFinite(n));
36
+ maxByField.set(col.field, nums.length ? Math.max(...nums) : 1);
37
+ }
38
+ }
39
+ const toggleRow = (id) => {
40
+ setSelected(selected[0] === id ? [] : [id]);
41
+ };
42
+ return (_jsxs("div", { "data-slot": "chart-data-grid", className: cn("spk-chart-data-grid", className), children: [hideChart ? null : chartType === "pie" ? (_jsx(PieChart, { height: height, hideLegend: hideLegend, series: [
43
+ {
44
+ innerRadius: 36,
45
+ paddingAngle: 2,
46
+ data: rows.map((row, i) => ({
47
+ id: row.id,
48
+ value: values[i] ?? 0,
49
+ label: categories[i],
50
+ color: selected.length && !selected.includes(row.id)
51
+ ? `color-mix(in srgb, ${chartColor(i)} 28%, transparent)`
52
+ : undefined,
53
+ })),
54
+ },
55
+ ] })) : (_jsx(ChartContainer, { height: height, hideLegend: hideLegend, highlightScope: "item", selected: selectedIndex >= 0 ? { seriesId: "value", dataIndex: selectedIndex } : null, xAxis: [{ data: categories }], series: [{ type: chartType, id: "value", label: valueField, data: values }], "aria-label": "Linked chart" })), _jsxs(Table, { containerClassName: "spk-chart-grid-table", children: [_jsx(TableHeader, { children: _jsx(TableRow, { children: columns.map((col) => (_jsx(TableHead, { style: col.width ? { width: col.width } : undefined, children: col.headerName }, col.field))) }) }), _jsx(TableBody, { children: rows.map((row, rowIndex) => (_jsx(TableRow, { "data-state": selected.includes(row.id) ? "selected" : undefined, onClick: () => toggleRow(row.id), style: { cursor: "pointer" }, children: columns.map((col, colIndex) => {
56
+ const value = row[col.field];
57
+ const color = chartColor(rowIndex);
58
+ let content;
59
+ if (col.type === "sparkline") {
60
+ content = renderChartCell(value, { variant: "sparkline", color, height: 32 });
61
+ }
62
+ else if (col.type === "bar") {
63
+ content = renderChartCell(value, {
64
+ variant: "bar",
65
+ color,
66
+ max: maxByField.get(col.field),
67
+ });
68
+ }
69
+ else if (col.type === "number" && typeof value === "number") {
70
+ content = formatChartNumber(value);
71
+ }
72
+ else {
73
+ content = value == null ? "—" : String(value);
74
+ }
75
+ return (_jsx(TableCell, { "data-field": col.field, children: colIndex === 0 ? (_jsx("span", { className: "spk-chart-grid-name", children: content })) : (content) }, col.field));
76
+ }) }, row.id))) })] })] }));
77
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from "react";
2
+ export type ContactLinkProps = {
3
+ href: string;
4
+ name: ReactNode;
5
+ label?: ReactNode;
6
+ icon: ReactNode;
7
+ iconBg?: string;
8
+ iconColor?: string;
9
+ className?: string;
10
+ target?: string;
11
+ rel?: string;
12
+ };
13
+ /** Contact / social row: tinted icon well, name, handle, trailing arrow. */
14
+ export declare function ContactLink({ href, name, label, icon, iconBg, iconColor, className, target, rel, }: ContactLinkProps): import("react").JSX.Element;
15
+ //# sourceMappingURL=ContactLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContactLink.d.ts","sourceRoot":"","sources":["../../src/composites/ContactLink.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,SAAS,EACT,MAAM,EACN,GAAG,GACJ,EAAE,gBAAgB,+BAsClB"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ import { Card } from "./Card";
4
+ /** Contact / social row: tinted icon well, name, handle, trailing arrow. */
5
+ export function ContactLink({ href, name, label, icon, iconBg, iconColor, className, target, rel, }) {
6
+ const external = href.startsWith("http");
7
+ return (_jsx("a", { "data-slot": "contact-link", href: href, target: target ?? (external ? "_blank" : undefined), rel: rel ?? (external ? "noopener noreferrer" : undefined), className: cn("group block rounded-2xl", className), children: _jsxs(Card, { variant: "panel", padding: "md", className: "flex items-center gap-4 p-4 group-hover:border-primary/25 group-hover:shadow-[0_8px_28px_color-mix(in_srgb,var(--chart-3)_18%,transparent)]", children: [_jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl transition-transform duration-200 group-hover:scale-110", style: { background: iconBg, color: iconColor }, children: icon }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-[13px] font-semibold text-foreground", children: name }), label ? _jsx("p", { className: "truncate text-[12px] text-muted-foreground", children: label }) : null] }), _jsx("svg", { className: "h-4 w-4 shrink-0 text-muted-foreground transition-colors group-hover:text-primary", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": true, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75" }) })] }) }));
8
+ }
@@ -38,7 +38,7 @@ export type CoverHeroProps = {
38
38
  className?: string;
39
39
  /** Offset used when the compact bar pins under app chrome. */
40
40
  compactOffsetClassName?: string;
41
- /** When false, skip writing cover-bleed attributes on `<html>` (catalog previews). */
41
+ /** When false, keep the cover inside this frame (docs / device previews). */
42
42
  bleed?: boolean;
43
43
  };
44
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"CoverHero.d.ts","sourceRoot":"","sources":["../../src/composites/CoverHero.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,sBAAsB,EAIvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,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,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,sFAAsF;IACtF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAY,EACZ,iBAAqB,EACrB,QAAQ,EACR,UAAU,EACV,SAAS,EACT,QAAc,EACd,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,OAAiB,EACjB,MAAM,EACN,SAAqB,EACrB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,SAAS,EACT,sBAAiC,EACjC,KAAY,GACb,EAAE,cAAc,+BAuQhB;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"CoverHero.d.ts","sourceRoot":"","sources":["../../src/composites/CoverHero.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,sBAAsB,EAIvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,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,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAY,EACZ,iBAAqB,EACrB,QAAQ,EACR,UAAU,EACV,SAAS,EACT,QAAc,EACd,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,OAAiB,EACjB,MAAM,EACN,SAAqB,EACrB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,SAAS,EACT,sBAAiC,EACjC,KAAY,GACb,EAAE,cAAc,+BA8QhB;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -55,7 +55,7 @@ export function CoverHero({ title, kicker, facts, avatars = [], hiddenAvatarCoun
55
55
  };
56
56
  }, []);
57
57
  useCoverChromeBleed(bleed && coverUnderChrome, scene.chromeInk);
58
- return (_jsxs(_Fragment, { children: [_jsxs("header", { ref: heroRef, "data-slot": "cover-hero", className: cn("relative z-10 w-full overflow-visible", className), children: [_jsxs("div", { className: cn(mediaClass, "sm:rounded-b-[1.75rem]"), "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: "relative min-h-[8.5rem] sm:min-h-[10.5rem] lg:min-h-[12rem]", children: _jsxs("div", { className: "absolute inset-x-0 top-0 z-30 flex items-start justify-between gap-2 px-3 pt-3 sm:px-5 sm:pt-4", children: [onBack ? (_jsxs("button", { type: "button", onClick: onBack, "aria-label": backLabel, "data-cover-ink": scene.headerInk, className: cn("cover-floating-shell flex items-center gap-1 px-3 py-1.5 text-xs font-semibold transition-colors active:scale-[0.96]", onDarkCover ? "text-white hover:bg-black/60" : "text-zinc-900 hover:bg-white/90"), children: [_jsx(ChevronLeft, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": true }), _jsx("span", { className: "hidden sm:inline", children: "Back" })] })) : (_jsx("span", {})), floatingActions ? (_jsx("div", { "data-cover-ink": scene.headerInk, className: "cover-floating-shell flex items-center gap-1 p-1", children: floatingActions })) : null] }) }), _jsx("div", { ref: plateRef, className: "relative z-20 px-3.5 pb-4 sm:px-5 sm:pb-5 lg:px-8 lg:pb-6", children: _jsxs("div", { className: "cover-identity story-identity", style: { "--story-avatar-count": avatarCount }, children: [_jsx("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-0 rounded-[1.35rem]", hasAvatars && "cover-identity__plate story-identity__plate", coverPlateClass(scene.headerInk)) }), _jsxs("div", { className: cn("relative z-10 flex flex-col items-center px-3 pb-3 text-center sm:px-6 sm:pb-4", hasAvatars ? "pt-0" : "pt-3 sm:pt-4"), children: [hasAvatars ? (_jsx("div", { className: "cover-identity__avatars story-identity__avatars", children: _jsxs("div", { className: "flex -space-x-5 sm:-space-x-6", children: [visibleAvatars.map((avatar, index) => {
58
+ return (_jsxs(_Fragment, { children: [_jsxs("header", { ref: heroRef, "data-slot": "cover-hero", "data-cover-bleed": bleed ? "true" : undefined, className: cn("relative z-10 w-full", bleed ? "overflow-visible" : "overflow-hidden rounded-[1.35rem] sm:rounded-[1.75rem]", className), children: [_jsxs("div", { className: cn(mediaClass, bleed && "sm:rounded-b-[1.75rem]"), "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: "relative min-h-[8.5rem] sm:min-h-[10.5rem] lg:min-h-[12rem]", children: _jsxs("div", { className: "absolute inset-x-0 top-0 z-30 flex items-start justify-between gap-2 px-3 pt-3 sm:px-5 sm:pt-4", children: [onBack ? (_jsxs("button", { type: "button", onClick: onBack, "aria-label": backLabel, "data-cover-ink": scene.headerInk, className: cn("cover-floating-shell flex items-center gap-1 px-3 py-1.5 text-xs font-semibold transition-colors active:scale-[0.96]", onDarkCover ? "text-white hover:bg-black/60" : "text-zinc-900 hover:bg-white/90"), children: [_jsx(ChevronLeft, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": true }), _jsx("span", { className: "hidden sm:inline", children: "Back" })] })) : (_jsx("span", {})), floatingActions ? (_jsx("div", { "data-cover-ink": scene.headerInk, className: "cover-floating-shell flex items-center gap-1 p-1", children: floatingActions })) : null] }) }), _jsx("div", { ref: plateRef, className: "relative z-20 px-3.5 pb-4 sm:px-5 sm:pb-5 lg:px-8 lg:pb-6", children: _jsxs("div", { className: "cover-identity story-identity", style: { "--story-avatar-count": avatarCount }, children: [_jsx("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-0 rounded-[1.35rem]", hasAvatars && "cover-identity__plate story-identity__plate", coverPlateClass(scene.headerInk)) }), _jsxs("div", { className: cn("relative z-10 flex flex-col items-center px-3 pb-3 text-center sm:px-6 sm:pb-4", hasAvatars ? "pt-0" : "pt-3 sm:pt-4"), children: [hasAvatars ? (_jsx("div", { className: "cover-identity__avatars story-identity__avatars", children: _jsxs("div", { className: "flex -space-x-5 sm:-space-x-6", children: [visibleAvatars.map((avatar, index) => {
59
59
  const body = (_jsx("span", { style: {
60
60
  width: "var(--story-avatar-size)",
61
61
  height: "var(--story-avatar-size)",
@@ -66,6 +66,6 @@ export function CoverHero({ title, kicker, facts, avatars = [], hiddenAvatarCoun
66
66
  height: "var(--story-avatar-size)",
67
67
  }, className: "relative z-0 flex items-center justify-center rounded-full border-[3px] border-white bg-zinc-900/80 text-base font-black text-white dark:border-white/30", children: ["+", extra] })) : null] }) })) : null, _jsxs("div", { className: cn("w-full min-w-0", hasAvatars && "mt-2 sm:mt-2.5"), children: [kicker ? (_jsx("div", { className: "flex flex-wrap items-center justify-center gap-1.5", children: kicker })) : null, _jsx("h1", { className: cn("mt-2 text-balance text-[1.15rem] font-black leading-tight tracking-tight sm:text-[1.35rem] lg:text-[1.65rem]", coverTitleClass(scene.headerInk)), children: title }), facts && facts.length > 0 ? (_jsx("dl", { className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-2 sm:flex sm:flex-wrap sm:justify-center sm:gap-x-6", children: facts.map((fact) => (_jsxs("div", { className: cn("flex min-w-0 items-center justify-center gap-2", fact.wide && "col-span-2 sm:col-span-1"), children: [fact.icon ? (_jsx("span", { className: cn("hidden h-7 w-7 shrink-0 items-center justify-center rounded-lg border backdrop-blur-md sm:flex", onDarkCover
68
68
  ? "border-white/20 bg-white/15 text-white/90"
69
- : "border-zinc-950/10 bg-zinc-950/[0.06] text-zinc-700"), children: fact.icon })) : null, _jsxs("div", { className: "min-w-0 text-center sm:text-left", children: [_jsx("dt", { className: cn("text-[9px] font-black uppercase tracking-[0.18em]", coverMutedClass(scene.headerInk)), children: fact.label }), _jsx("dd", { className: cn("truncate text-[11px] font-bold sm:text-xs", coverTitleClass(scene.headerInk), fact.muted && "opacity-60"), children: fact.value })] })] }, fact.key))) })) : null, children] })] })] }) })] })] }), _jsx("div", { className: cn("sticky z-[60] h-0", compactOffsetClassName), children: !heroInView ? (_jsx("div", { className: "glass-header cover-chrome-bar absolute inset-x-0 top-0 border-b border-border/50 bg-background/85 backdrop-blur-md dark:bg-background/94", children: _jsxs("div", { className: "app-frame-pad flex items-center gap-2 py-1.5 sm:py-2", children: [onBack ? (_jsx("button", { type: "button", onClick: onBack, "aria-label": backLabel, className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-xl text-foreground transition-colors hover:bg-muted", children: _jsx(ChevronLeft, { className: "h-4 w-4", "aria-hidden": true }) })) : null, _jsx("h2", { className: "page-header-title min-w-0 flex-1 truncate", children: title }), compactActions] }) })) : null })] }));
69
+ : "border-zinc-950/10 bg-zinc-950/[0.06] text-zinc-700"), children: fact.icon })) : null, _jsxs("div", { className: "min-w-0 text-center sm:text-left", children: [_jsx("dt", { className: cn("text-[9px] font-black uppercase tracking-[0.18em]", coverMutedClass(scene.headerInk)), children: fact.label }), _jsx("dd", { className: cn("truncate text-[11px] font-bold sm:text-xs", coverTitleClass(scene.headerInk), fact.muted && "opacity-60"), children: fact.value })] })] }, fact.key))) })) : null, children] })] })] }) })] })] }), bleed ? (_jsx("div", { className: cn("sticky z-[60] h-0", compactOffsetClassName), children: !heroInView ? (_jsx("div", { className: "glass-header cover-chrome-bar absolute inset-x-0 top-0 border-b border-border/50 bg-background/85 backdrop-blur-md dark:bg-background/94", children: _jsxs("div", { className: "app-frame-pad flex items-center gap-2 py-1.5 sm:py-2", children: [onBack ? (_jsx("button", { type: "button", onClick: onBack, "aria-label": backLabel, className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-xl text-foreground transition-colors hover:bg-muted", children: _jsx(ChevronLeft, { className: "h-4 w-4", "aria-hidden": true }) })) : null, _jsx("h2", { className: "page-header-title min-w-0 flex-1 truncate", children: title }), compactActions] }) })) : null })) : null] }));
70
70
  }
71
71
  export { coverFloatingIconClass };
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ export type DisplayHeadingProps = {
3
+ children: ReactNode;
4
+ as?: "h1" | "h2";
5
+ className?: string;
6
+ };
7
+ /** Oversized marketing hero title. Compose with Wordmark / GradientText. */
8
+ export declare function DisplayHeading({ children, as: Tag, className, }: DisplayHeadingProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=DisplayHeading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DisplayHeading.d.ts","sourceRoot":"","sources":["../../src/composites/DisplayHeading.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,EAAE,EAAE,GAAU,EACd,SAAS,GACV,EAAE,mBAAmB,+BAYrB"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn";
3
+ /** Oversized marketing hero title. Compose with Wordmark / GradientText. */
4
+ export function DisplayHeading({ children, as: Tag = "h1", className, }) {
5
+ return (_jsx(Tag, { "data-slot": "display-heading", className: cn("text-[clamp(2.5rem,8vw,5.5rem)] font-[900] leading-[0.95] tracking-tight", className), children: children }));
6
+ }
@@ -19,7 +19,7 @@ export type EntityMediaCardProps = {
19
19
  imageClassName?: string;
20
20
  };
21
21
  /**
22
- * Entity card with photo (or initials fallback) — contact / directory style.
22
+ * Entity card with photo (or generated cover + initials) — contact / album tile.
23
23
  */
24
24
  export declare function EntityMediaCard({ title, subtitle, statusLine, imageUrl, hideImage, fallbackLabel, tags, overlays, menu, meta, href, onClick, size, orientation, className, imageClassName, }: EntityMediaCardProps): import("react").JSX.Element;
25
25
  //# sourceMappingURL=EntityMediaCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityMediaCard.d.ts","sourceRoot":"","sources":["../../src/composites/EntityMediaCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6BAA6B;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,IAAc,EACd,WAAqB,EACrB,SAAS,EACT,cAAc,GACf,EAAE,oBAAoB,+BA0EtB"}
1
+ {"version":3,"file":"EntityMediaCard.d.ts","sourceRoot":"","sources":["../../src/composites/EntityMediaCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6BAA6B;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,IAAc,EACd,WAAqB,EACrB,SAAS,EACT,cAAc,GACf,EAAE,oBAAoB,+BAyFtB"}
@@ -1,7 +1,10 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/cn";
3
+ import { coverTitleClass } from "../lib/cover-chrome";
4
+ import { getCoverPattern } from "../lib/cover-pattern";
5
+ import { CoverPattern } from "./CoverPattern";
3
6
  /**
4
- * Entity card with photo (or initials fallback) — contact / directory style.
7
+ * Entity card with photo (or generated cover + initials) — contact / album tile.
5
8
  */
6
9
  export function EntityMediaCard({ title, subtitle, statusLine, imageUrl, hideImage, fallbackLabel, tags, overlays, menu, meta, href, onClick, size = "large", orientation = "stack", className, imageClassName, }) {
7
10
  const Comp = href ? "a" : onClick ? "button" : "div";
@@ -12,6 +15,11 @@ export function EntityMediaCard({ title, subtitle, statusLine, imageUrl, hideIma
12
15
  .map((w) => w[0]?.toUpperCase() ?? "")
13
16
  .join("") ||
14
17
  "?";
15
- const photoAspect = size === "compact" ? "aspect-square" : size === "small" ? "aspect-[4/3]" : "aspect-square";
16
- return (_jsxs(Comp, { href: href, type: onClick && !href ? "button" : undefined, onClick: onClick, "data-slot": "entity-media-card", className: cn("group flex overflow-hidden rounded-2xl border border-white/45 bg-card text-left shadow-[0_8px_30px_rgb(0,0,0,0.04)] transition-[transform,border-color] duration-200 dark:border-white/12", "hover:-translate-y-0.5 hover:border-primary/15", orientation === "row" ? "flex-row" : "flex-col", className), children: [_jsxs("div", { className: cn("relative shrink-0 overflow-hidden bg-muted", orientation === "row" ? "w-[42%] min-w-[7rem]" : "w-full", orientation === "stack" && photoAspect, imageClassName), children: [!hideImage && imageUrl ? (_jsx("img", { src: imageUrl, alt: "", className: "size-full object-cover transition-transform duration-700 group-hover:scale-110" })) : (_jsx("div", { className: "flex size-full items-center justify-center bg-gradient-to-br from-primary/20 via-muted to-accent-highlight/20 text-2xl font-black text-primary", children: initials })), overlays ? _jsx("div", { className: "absolute inset-0 p-2", children: overlays }) : null] }), _jsxs("div", { className: cn("relative flex min-w-0 flex-1 flex-col bg-white dark:bg-card", size === "compact" ? "gap-1 p-2.5" : "gap-1.5 p-3 sm:p-4"), children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "truncate font-bold tracking-tight group-hover:text-primary", children: title }), subtitle ? (_jsx("p", { className: "truncate text-xs font-medium text-muted-foreground", children: subtitle })) : null, statusLine ? (_jsx("p", { className: "mt-0.5 text-[9px] font-bold uppercase tracking-widest text-muted-foreground/80", children: statusLine })) : null] }), menu] }), meta, tags ? _jsx("div", { className: "mt-auto flex flex-wrap gap-1 pt-1", children: tags }) : null] })] }));
18
+ const scene = getCoverPattern({ seed: title, hue: 210 });
19
+ const photoAspect = orientation === "row"
20
+ ? "h-full min-h-[6.5rem]"
21
+ : size === "compact"
22
+ ? "aspect-square"
23
+ : "aspect-[4/3]";
24
+ return (_jsxs(Comp, { href: href, type: onClick && !href ? "button" : undefined, onClick: onClick, "data-slot": "entity-media-card", "data-size": size, "data-orientation": orientation, className: cn("group flex h-full min-w-0 overflow-hidden rounded-2xl border border-border/60 bg-card text-left shadow-[0_8px_30px_color-mix(in_srgb,var(--foreground)_6%,transparent)] transition-[transform,border-color] duration-200", "hover:-translate-y-0.5 hover:border-primary/25", orientation === "row" ? "flex-row items-stretch" : "flex-col", className), children: [_jsxs("div", { className: cn("relative shrink-0 overflow-hidden bg-muted", orientation === "row" ? "w-[38%] min-w-[6.5rem] max-w-[9.5rem]" : "w-full", photoAspect, imageClassName), children: [!hideImage && imageUrl ? (_jsx("img", { src: imageUrl, alt: "", className: "absolute inset-0 size-full object-cover transition-transform duration-700 group-hover:scale-110" })) : (_jsxs(_Fragment, { children: [_jsx(CoverPattern, { seed: title, hue: 210 }), _jsx("div", { className: cn("absolute inset-0 flex items-center justify-center text-2xl font-black", coverTitleClass(scene.headerInk)), children: initials })] })), overlays ? _jsx("div", { className: "absolute inset-0 p-2", children: overlays }) : null] }), _jsxs("div", { className: cn("relative flex min-w-0 flex-1 flex-col justify-center bg-card", size === "compact" ? "gap-1 p-2.5" : "gap-1 p-3 sm:p-3.5"), children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "truncate font-bold tracking-tight group-hover:text-primary", children: title }), subtitle ? (_jsx("p", { className: "truncate text-xs font-medium text-muted-foreground", children: subtitle })) : null, statusLine ? (_jsx("p", { className: "mt-0.5 text-[9px] font-bold uppercase tracking-widest text-muted-foreground/80", children: statusLine })) : null] }), menu] }), meta, tags ? _jsx("div", { className: "mt-auto flex flex-wrap gap-1 pt-1", children: tags }) : null] })] }));
17
25
  }
@@ -0,0 +1,35 @@
1
+ import { type CalendarView, type SchedulerEvent, type SchedulerPreferences, type SchedulerResource } from "../lib/scheduler";
2
+ export type EventCalendarProps = {
3
+ events?: SchedulerEvent[];
4
+ resources?: SchedulerResource[];
5
+ view?: CalendarView;
6
+ defaultView?: CalendarView;
7
+ onViewChange?: (view: CalendarView) => void;
8
+ date?: Date;
9
+ defaultDate?: Date;
10
+ onDateChange?: (date: Date) => void;
11
+ views?: CalendarView[];
12
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
13
+ hourStart?: number;
14
+ hourEnd?: number;
15
+ locale?: string;
16
+ readOnly?: boolean;
17
+ areEventsDraggable?: boolean;
18
+ areEventsResizable?: boolean;
19
+ preferences?: SchedulerPreferences;
20
+ defaultPreferences?: SchedulerPreferences;
21
+ onPreferencesChange?: (preferences: Required<SchedulerPreferences>) => void;
22
+ onEventClick?: (event: SchedulerEvent) => void;
23
+ onEventChange?: (event: SchedulerEvent, next: Partial<SchedulerEvent>) => void;
24
+ onEventCreate?: (event: SchedulerEvent) => void;
25
+ onEventDelete?: (event: SchedulerEvent) => void;
26
+ onSlotClick?: (slot: {
27
+ start: Date;
28
+ end: Date;
29
+ allDay: boolean;
30
+ }) => void;
31
+ className?: string;
32
+ };
33
+ /** Month / week / day / agenda calendar with editor, resize, recurrence, and preferences. */
34
+ export declare function EventCalendar({ events, resources, view: viewProp, defaultView, onViewChange, date: dateProp, defaultDate, onDateChange, views, weekStartsOn, hourStart, hourEnd, locale, readOnly, areEventsDraggable, areEventsResizable, preferences, defaultPreferences, onPreferencesChange, onEventClick, onEventChange, onEventCreate, onEventDelete, onSlotClick, className, }: EventCalendarProps): import("react").JSX.Element;
35
+ //# sourceMappingURL=EventCalendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventCalendar.d.ts","sourceRoot":"","sources":["../../src/composites/EventCalendar.tsx"],"names":[],"mappings":"AAWA,OAAO,EAkCL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAY1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;IAC5E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC/E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAuDF,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,EAC5B,MAAW,EACX,SAAc,EACd,IAAI,EAAE,QAAQ,EACd,WAAqB,EACrB,YAAY,EACZ,IAAI,EAAE,QAAQ,EACd,WAAW,EACX,YAAY,EACZ,KAA0C,EAC1C,YAAgB,EAChB,SAAa,EACb,OAAY,EACZ,MAAM,EACN,QAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EACX,SAAS,GACV,EAAE,kBAAkB,+BAiTpB"}