@arbidocs/blocks 0.3.185 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (612) hide show
  1. package/README.md +122 -0
  2. package/dist/agents/approvals/AuthorizeAgentParts.d.ts +79 -0
  3. package/dist/agents/approvals/ConsentPage.d.ts +76 -0
  4. package/dist/agents/approvals/ConsentParts.d.ts +37 -0
  5. package/dist/agents/approvals/index.d.ts +3 -0
  6. package/dist/agents/config/ConfigField.d.ts +43 -0
  7. package/dist/agents/config/ConfigForm.d.ts +35 -0
  8. package/dist/agents/config/TupleArrayField.d.ts +32 -0
  9. package/dist/agents/config/index.d.ts +4 -0
  10. package/dist/agents/config/schema-utils.d.ts +28 -0
  11. package/dist/agents/definitions/AgentCard.d.ts +63 -0
  12. package/dist/agents/definitions/AgentCreator.d.ts +118 -0
  13. package/dist/agents/definitions/AgentEditorParts.d.ts +63 -0
  14. package/dist/agents/definitions/AgentGallery.d.ts +29 -0
  15. package/dist/agents/definitions/index.d.ts +4 -0
  16. package/dist/agents/index.cjs +595 -0
  17. package/dist/agents/index.cjs.map +1 -0
  18. package/dist/agents/index.d.ts +7 -0
  19. package/dist/agents/index.js +14 -0
  20. package/dist/agents/index.js.map +1 -0
  21. package/dist/agents/runs/AgentBar.d.ts +103 -0
  22. package/dist/agents/runs/AgentSteps.d.ts +157 -0
  23. package/dist/agents/runs/SubagentRoster.d.ts +37 -0
  24. package/dist/agents/runs/index.d.ts +3 -0
  25. package/dist/agents/skills/SkillBrowserParts.d.ts +70 -0
  26. package/dist/agents/skills/SkillCard.d.ts +48 -0
  27. package/dist/agents/skills/SkillForms.d.ts +64 -0
  28. package/dist/agents/skills/SkillParts.d.ts +31 -0
  29. package/dist/agents/skills/SkillRow.d.ts +34 -0
  30. package/dist/agents/skills/index.d.ts +5 -0
  31. package/dist/agents/tasks/LiveRunsBanner.d.ts +26 -0
  32. package/dist/agents/tasks/RecurrenceBuilder.d.ts +36 -0
  33. package/dist/agents/tasks/TaskComposer.d.ts +108 -0
  34. package/dist/agents/tasks/TaskPlan.d.ts +78 -0
  35. package/dist/agents/tasks/TaskRowActions.d.ts +43 -0
  36. package/dist/agents/tasks/TaskRunsDialog.d.ts +45 -0
  37. package/dist/agents/tasks/TasksChrome.d.ts +36 -0
  38. package/dist/agents/tasks/UploadTaskItem.d.ts +39 -0
  39. package/dist/agents/tasks/UploadTaskList.d.ts +35 -0
  40. package/dist/agents/tasks/elapsed.d.ts +2 -0
  41. package/dist/agents/tasks/index.d.ts +13 -0
  42. package/dist/agents/tasks/rrule.d.ts +36 -0
  43. package/dist/agents/tasks/taskColumns.d.ts +68 -0
  44. package/dist/agents/tasks/taskLabels.d.ts +26 -0
  45. package/dist/agents/workflows/AgentSelect.d.ts +33 -0
  46. package/dist/agents/workflows/SchemaForm.d.ts +37 -0
  47. package/dist/agents/workflows/WorkflowConfigDialog.d.ts +73 -0
  48. package/dist/agents/workflows/WorkflowLauncher.d.ts +38 -0
  49. package/dist/agents/workflows/index.d.ts +6 -0
  50. package/dist/agents/workflows/types.d.ts +125 -0
  51. package/dist/agents/workflows/workflow.d.ts +62 -0
  52. package/dist/auth/AuthFooter.d.ts +56 -0
  53. package/dist/auth/AuthForm.d.ts +105 -0
  54. package/dist/auth/AuthLayout.d.ts +46 -0
  55. package/dist/auth/PasswordStrengthInput.d.ts +44 -0
  56. package/dist/auth/RecoveryDialogs.d.ts +90 -0
  57. package/dist/auth/SsoLoginButton.d.ts +19 -0
  58. package/dist/auth/index.cjs +123 -0
  59. package/dist/auth/index.cjs.map +1 -0
  60. package/dist/auth/index.d.ts +6 -0
  61. package/dist/auth/index.js +6 -0
  62. package/dist/auth/index.js.map +1 -0
  63. package/dist/builder/AgentsPanel.d.ts +9 -0
  64. package/dist/builder/ModuleManager.d.ts +6 -0
  65. package/dist/builder/VerticalBuilder.d.ts +32 -0
  66. package/dist/builder/agents/store.d.ts +21 -0
  67. package/dist/builder/export.d.ts +30 -0
  68. package/dist/builder/modules/registry.d.ts +11 -0
  69. package/dist/builder/modules/store.d.ts +29 -0
  70. package/dist/builder/modules/types.d.ts +29 -0
  71. package/dist/builder/types.d.ts +28 -0
  72. package/dist/chat/BranchControls.d.ts +33 -0
  73. package/dist/chat/Composer.d.ts +156 -0
  74. package/dist/chat/ContextChip.d.ts +19 -0
  75. package/dist/chat/ContextPanel.d.ts +108 -0
  76. package/dist/chat/ConversationEmpty.d.ts +53 -0
  77. package/dist/chat/ConversationLayout.d.ts +40 -0
  78. package/dist/chat/ConversationParts.d.ts +62 -0
  79. package/dist/chat/ConversationSearchView.d.ts +57 -0
  80. package/dist/chat/LabelPinRow.d.ts +30 -0
  81. package/dist/chat/Message.d.ts +189 -0
  82. package/dist/chat/MessageAlert.d.ts +25 -0
  83. package/dist/chat/MessageList.d.ts +102 -0
  84. package/dist/chat/ModelPicker.d.ts +103 -0
  85. package/dist/chat/PendingAnswerBar.d.ts +36 -0
  86. package/dist/chat/PinnedDocChip.d.ts +22 -0
  87. package/dist/chat/SlashMenu.d.ts +57 -0
  88. package/dist/chat/ThreadMap.d.ts +45 -0
  89. package/dist/chat/index.cjs +423 -0
  90. package/dist/chat/index.cjs.map +1 -0
  91. package/dist/chat/index.d.ts +21 -0
  92. package/dist/chat/index.js +6 -0
  93. package/dist/chat/index.js.map +1 -0
  94. package/dist/chat/test-id.d.ts +16 -0
  95. package/dist/chat/useStreamAnnouncement.d.ts +19 -0
  96. package/dist/chunk-223D4727.cjs +50 -0
  97. package/dist/chunk-223D4727.cjs.map +1 -0
  98. package/dist/chunk-2K33YGM6.cjs +1846 -0
  99. package/dist/chunk-2K33YGM6.cjs.map +1 -0
  100. package/dist/chunk-2ORA62OF.js +266 -0
  101. package/dist/chunk-2ORA62OF.js.map +1 -0
  102. package/dist/chunk-4EZVCGRL.js +803 -0
  103. package/dist/chunk-4EZVCGRL.js.map +1 -0
  104. package/dist/chunk-54Q3RNJU.cjs +516 -0
  105. package/dist/chunk-54Q3RNJU.cjs.map +1 -0
  106. package/dist/chunk-5B4PXAKI.cjs +287 -0
  107. package/dist/chunk-5B4PXAKI.cjs.map +1 -0
  108. package/dist/chunk-6HIPFEID.cjs +574 -0
  109. package/dist/chunk-6HIPFEID.cjs.map +1 -0
  110. package/dist/{chunk-FZ2S6VAZ.js → chunk-6P6AEQJB.js} +413 -1132
  111. package/dist/chunk-6P6AEQJB.js.map +1 -0
  112. package/dist/chunk-76JDDMSP.js +31 -0
  113. package/dist/chunk-76JDDMSP.js.map +1 -0
  114. package/dist/chunk-7F6CBP3Z.js +12 -0
  115. package/dist/chunk-7F6CBP3Z.js.map +1 -0
  116. package/dist/chunk-7G2LJMUG.cjs +45 -0
  117. package/dist/chunk-7G2LJMUG.cjs.map +1 -0
  118. package/dist/chunk-7PEELPMA.js +1799 -0
  119. package/dist/chunk-7PEELPMA.js.map +1 -0
  120. package/dist/chunk-A2YAC22G.js +93 -0
  121. package/dist/chunk-A2YAC22G.js.map +1 -0
  122. package/dist/chunk-ADOKTJHV.cjs +262 -0
  123. package/dist/chunk-ADOKTJHV.cjs.map +1 -0
  124. package/dist/chunk-AE5FHFZ5.cjs +272 -0
  125. package/dist/chunk-AE5FHFZ5.cjs.map +1 -0
  126. package/dist/chunk-AXIZ2MDV.js +751 -0
  127. package/dist/chunk-AXIZ2MDV.js.map +1 -0
  128. package/dist/chunk-AZQDNYH4.js +2865 -0
  129. package/dist/chunk-AZQDNYH4.js.map +1 -0
  130. package/dist/chunk-C54XEN5T.cjs +34 -0
  131. package/dist/chunk-C54XEN5T.cjs.map +1 -0
  132. package/dist/chunk-CQCC7LE7.js +210 -0
  133. package/dist/chunk-CQCC7LE7.js.map +1 -0
  134. package/dist/chunk-CRIKTUEU.cjs +47 -0
  135. package/dist/chunk-CRIKTUEU.cjs.map +1 -0
  136. package/dist/chunk-CTZ5745I.js +564 -0
  137. package/dist/chunk-CTZ5745I.js.map +1 -0
  138. package/dist/chunk-DPLRHEJZ.js +78 -0
  139. package/dist/chunk-DPLRHEJZ.js.map +1 -0
  140. package/dist/{chunk-DBAUZD7A.cjs → chunk-DREI7EQ2.cjs} +437 -1152
  141. package/dist/chunk-DREI7EQ2.cjs.map +1 -0
  142. package/dist/chunk-ELR74ME6.cjs +68 -0
  143. package/dist/chunk-ELR74ME6.cjs.map +1 -0
  144. package/dist/chunk-G3G7LZPM.cjs +205 -0
  145. package/dist/chunk-G3G7LZPM.cjs.map +1 -0
  146. package/dist/chunk-GDFWJ73C.cjs +2973 -0
  147. package/dist/chunk-GDFWJ73C.cjs.map +1 -0
  148. package/dist/chunk-ITGHMJOM.js +5528 -0
  149. package/dist/chunk-ITGHMJOM.js.map +1 -0
  150. package/dist/chunk-J2BGSWXM.cjs +990 -0
  151. package/dist/chunk-J2BGSWXM.cjs.map +1 -0
  152. package/dist/chunk-K4BGOPGG.js +79 -0
  153. package/dist/chunk-K4BGOPGG.js.map +1 -0
  154. package/dist/chunk-LGBAZD37.js +341 -0
  155. package/dist/chunk-LGBAZD37.js.map +1 -0
  156. package/dist/chunk-LRUCMZK6.cjs +680 -0
  157. package/dist/chunk-LRUCMZK6.cjs.map +1 -0
  158. package/dist/chunk-MHVNT4J3.cjs +15 -0
  159. package/dist/chunk-MHVNT4J3.cjs.map +1 -0
  160. package/dist/chunk-NBV56SGU.js +42 -0
  161. package/dist/chunk-NBV56SGU.js.map +1 -0
  162. package/dist/chunk-NPLYHR2E.js +13 -0
  163. package/dist/chunk-NPLYHR2E.js.map +1 -0
  164. package/dist/chunk-NUNKSZKU.js +203 -0
  165. package/dist/chunk-NUNKSZKU.js.map +1 -0
  166. package/dist/chunk-OB5F4577.cjs +40 -0
  167. package/dist/chunk-OB5F4577.cjs.map +1 -0
  168. package/dist/chunk-OBLSURHV.js +973 -0
  169. package/dist/chunk-OBLSURHV.js.map +1 -0
  170. package/dist/chunk-OUW6G4O2.cjs +96 -0
  171. package/dist/chunk-OUW6G4O2.cjs.map +1 -0
  172. package/dist/chunk-OVEQERPO.js +66 -0
  173. package/dist/chunk-OVEQERPO.js.map +1 -0
  174. package/dist/chunk-P6GHJSLR.js +34 -0
  175. package/dist/chunk-P6GHJSLR.js.map +1 -0
  176. package/dist/chunk-PCB2BPN3.cjs +41 -0
  177. package/dist/chunk-PCB2BPN3.cjs.map +1 -0
  178. package/dist/chunk-PPCATBOY.cjs +15 -0
  179. package/dist/chunk-PPCATBOY.cjs.map +1 -0
  180. package/dist/chunk-QN42OA5J.js +887 -0
  181. package/dist/chunk-QN42OA5J.js.map +1 -0
  182. package/dist/chunk-QXEJXIP4.js +675 -0
  183. package/dist/chunk-QXEJXIP4.js.map +1 -0
  184. package/dist/chunk-RC6VTY2H.js +47 -0
  185. package/dist/chunk-RC6VTY2H.js.map +1 -0
  186. package/dist/chunk-RFIBUWLF.cjs +232 -0
  187. package/dist/chunk-RFIBUWLF.cjs.map +1 -0
  188. package/dist/chunk-S7PSMMRG.js +38 -0
  189. package/dist/chunk-S7PSMMRG.js.map +1 -0
  190. package/dist/chunk-SCFYPAG6.cjs +18 -0
  191. package/dist/chunk-SCFYPAG6.cjs.map +1 -0
  192. package/dist/chunk-SYDHKKRZ.cjs +818 -0
  193. package/dist/chunk-SYDHKKRZ.cjs.map +1 -0
  194. package/dist/chunk-TX2ZICS7.js +139 -0
  195. package/dist/chunk-TX2ZICS7.js.map +1 -0
  196. package/dist/chunk-TYZUCAT7.js +787 -0
  197. package/dist/chunk-TYZUCAT7.js.map +1 -0
  198. package/dist/chunk-U2E3WT3J.js +45 -0
  199. package/dist/chunk-U2E3WT3J.js.map +1 -0
  200. package/dist/chunk-UBNVIIBT.js +284 -0
  201. package/dist/chunk-UBNVIIBT.js.map +1 -0
  202. package/dist/chunk-UFHMLHIR.cjs +66 -0
  203. package/dist/chunk-UFHMLHIR.cjs.map +1 -0
  204. package/dist/chunk-UJE32SST.js +39 -0
  205. package/dist/chunk-UJE32SST.js.map +1 -0
  206. package/dist/chunk-ULWRNGGE.cjs +146 -0
  207. package/dist/chunk-ULWRNGGE.cjs.map +1 -0
  208. package/dist/chunk-UWGIB3VQ.js +64 -0
  209. package/dist/chunk-UWGIB3VQ.js.map +1 -0
  210. package/dist/chunk-V4ISCZJ7.cjs +207 -0
  211. package/dist/chunk-V4ISCZJ7.cjs.map +1 -0
  212. package/dist/chunk-VFUWWH52.cjs +83 -0
  213. package/dist/chunk-VFUWWH52.cjs.map +1 -0
  214. package/dist/chunk-VILAPTCB.js +259 -0
  215. package/dist/chunk-VILAPTCB.js.map +1 -0
  216. package/dist/chunk-VLCY46K6.cjs +82 -0
  217. package/dist/chunk-VLCY46K6.cjs.map +1 -0
  218. package/dist/chunk-VPPX5XUF.cjs +813 -0
  219. package/dist/chunk-VPPX5XUF.cjs.map +1 -0
  220. package/dist/chunk-WJMEXTVD.cjs +122 -0
  221. package/dist/chunk-WJMEXTVD.cjs.map +1 -0
  222. package/dist/chunk-WTNMWEBC.js +504 -0
  223. package/dist/chunk-WTNMWEBC.js.map +1 -0
  224. package/dist/chunk-WW6EOVZA.js +112 -0
  225. package/dist/chunk-WW6EOVZA.js.map +1 -0
  226. package/dist/chunk-XNBAXRY7.cjs +5673 -0
  227. package/dist/chunk-XNBAXRY7.cjs.map +1 -0
  228. package/dist/chunk-XQ7PKKDY.cjs +787 -0
  229. package/dist/chunk-XQ7PKKDY.cjs.map +1 -0
  230. package/dist/chunk-XZIYRKLW.cjs +347 -0
  231. package/dist/chunk-XZIYRKLW.cjs.map +1 -0
  232. package/dist/chunk-YBXCZEWS.js +187 -0
  233. package/dist/chunk-YBXCZEWS.js.map +1 -0
  234. package/dist/chunk-YDHO4AVL.js +16 -0
  235. package/dist/chunk-YDHO4AVL.js.map +1 -0
  236. package/dist/chunk-ZORQ5M3W.cjs +934 -0
  237. package/dist/chunk-ZORQ5M3W.cjs.map +1 -0
  238. package/dist/chunk-ZW6FPIFC.cjs +36 -0
  239. package/dist/chunk-ZW6FPIFC.cjs.map +1 -0
  240. package/dist/citations/CitationEditor.d.ts +58 -0
  241. package/dist/citations/PassagePill.d.ts +49 -0
  242. package/dist/citations/QuietMarks.d.ts +81 -0
  243. package/dist/citations/index.cjs +47 -0
  244. package/dist/citations/index.cjs.map +1 -0
  245. package/dist/citations/index.d.ts +3 -0
  246. package/dist/citations/index.js +6 -0
  247. package/dist/citations/index.js.map +1 -0
  248. package/dist/collaboration/contacts/AddContactsParts.d.ts +46 -0
  249. package/dist/collaboration/contacts/index.d.ts +1 -0
  250. package/dist/collaboration/direct-messages/DirectMessages.d.ts +33 -0
  251. package/dist/collaboration/direct-messages/DmParts.d.ts +139 -0
  252. package/dist/collaboration/direct-messages/index.d.ts +2 -0
  253. package/dist/collaboration/index.cjs +141 -0
  254. package/dist/collaboration/index.cjs.map +1 -0
  255. package/dist/collaboration/index.d.ts +5 -0
  256. package/dist/collaboration/index.js +8 -0
  257. package/dist/collaboration/index.js.map +1 -0
  258. package/dist/collaboration/mail/MailFolderTree.d.ts +34 -0
  259. package/dist/collaboration/mail/index.d.ts +2 -0
  260. package/dist/collaboration/mail/mailFolders.d.ts +25 -0
  261. package/dist/collaboration/members/WorkspaceMembers.d.ts +74 -0
  262. package/dist/collaboration/members/index.d.ts +1 -0
  263. package/dist/collaboration/sharing/ShareControl.d.ts +38 -0
  264. package/dist/collaboration/sharing/index.d.ts +1 -0
  265. package/dist/components/Accordion.d.ts +12 -0
  266. package/dist/components/ActionLink.d.ts +18 -0
  267. package/dist/components/AskBar.d.ts +48 -0
  268. package/dist/components/AvatarBlock.d.ts +9 -0
  269. package/dist/components/Banner.d.ts +12 -0
  270. package/dist/components/BlockImage.d.ts +18 -0
  271. package/dist/components/CTABanner.d.ts +17 -0
  272. package/dist/components/Callout.d.ts +9 -0
  273. package/dist/components/Chart.d.ts +35 -0
  274. package/dist/components/CollectionDetail.d.ts +23 -0
  275. package/dist/components/Columns.d.ts +11 -0
  276. package/dist/components/ContactForm.d.ts +54 -0
  277. package/dist/components/Container.d.ts +11 -0
  278. package/dist/components/DataTable.d.ts +47 -0
  279. package/dist/components/DataTableBlock.d.ts +26 -0
  280. package/dist/components/EmptyState.d.ts +11 -0
  281. package/dist/components/EntityChip.d.ts +24 -0
  282. package/dist/components/EntityIdentityBar.d.ts +90 -0
  283. package/dist/components/EntityTooltip.d.ts +43 -0
  284. package/dist/components/FAQ.d.ts +14 -0
  285. package/dist/components/FeatureGrid.d.ts +18 -0
  286. package/dist/components/Footer.d.ts +25 -0
  287. package/dist/components/Gallery.d.ts +15 -0
  288. package/dist/components/Hero.d.ts +35 -0
  289. package/dist/components/ListBlock.d.ts +10 -0
  290. package/dist/components/LogoCloud.d.ts +12 -0
  291. package/dist/components/MediaText.d.ts +15 -0
  292. package/dist/components/MemberAvatarStack.d.ts +36 -0
  293. package/dist/components/MetricCard.d.ts +28 -0
  294. package/dist/components/Navbar.d.ts +39 -0
  295. package/dist/components/PageHeader.d.ts +15 -0
  296. package/dist/components/PricingTable.d.ts +19 -0
  297. package/dist/components/RichTextBlock.d.ts +10 -0
  298. package/dist/components/SectionHeading.d.ts +11 -0
  299. package/dist/components/Spacer.d.ts +7 -0
  300. package/dist/components/StatGroup.d.ts +12 -0
  301. package/dist/components/Steps.d.ts +12 -0
  302. package/dist/components/Tabs.d.ts +15 -0
  303. package/dist/components/TeamGrid.d.ts +30 -0
  304. package/dist/components/Testimonial.d.ts +9 -0
  305. package/dist/components/TestimonialGrid.d.ts +13 -0
  306. package/dist/components/ToneBadge.d.ts +18 -0
  307. package/dist/components/Toolbar.d.ts +11 -0
  308. package/dist/components/UsageMeter.d.ts +21 -0
  309. package/dist/components/VideoEmbed.d.ts +16 -0
  310. package/dist/components/assetImage.d.ts +16 -0
  311. package/dist/components/assetResolver.d.ts +57 -0
  312. package/dist/components/blockLink.d.ts +26 -0
  313. package/dist/components/editorial/ArticleList.d.ts +32 -0
  314. package/dist/components/editorial/Bands.d.ts +29 -0
  315. package/dist/components/editorial/EditorialHeading.d.ts +17 -0
  316. package/dist/components/editorial/EditorialHero.d.ts +46 -0
  317. package/dist/components/editorial/EditorialSection.d.ts +47 -0
  318. package/dist/components/editorial/Eyebrow.d.ts +14 -0
  319. package/dist/components/editorial/PanelGrid.d.ts +45 -0
  320. package/dist/components/editorial/ProfileCard.d.ts +27 -0
  321. package/dist/components/editorial/PullQuote.d.ts +17 -0
  322. package/dist/components/editorial/Reveal.d.ts +15 -0
  323. package/dist/components/editorial/index.d.ts +12 -0
  324. package/dist/components/editorial/lists.d.ts +42 -0
  325. package/dist/components/editorial/tone.d.ts +33 -0
  326. package/dist/components/tones.d.ts +14 -0
  327. package/dist/connect/index.cjs +65 -0
  328. package/dist/connect/index.cjs.map +1 -0
  329. package/dist/connect/index.d.ts +8 -0
  330. package/dist/connect/index.js +28 -0
  331. package/dist/connect/index.js.map +1 -0
  332. package/dist/connection/ArbiAppProvider.d.ts +16 -0
  333. package/dist/connection/ConnectionProvider.d.ts +50 -0
  334. package/dist/connection/ai.d.ts +99 -0
  335. package/dist/connection/types.d.ts +54 -0
  336. package/dist/connection/useImageGen.d.ts +22 -0
  337. package/dist/facts/FactComposer.d.ts +75 -0
  338. package/dist/facts/FactDateInput.d.ts +34 -0
  339. package/dist/facts/FactLabelsCell.d.ts +35 -0
  340. package/dist/facts/FactPassages.d.ts +52 -0
  341. package/dist/facts/FactRowActions.d.ts +18 -0
  342. package/dist/facts/FactSearchParts.d.ts +80 -0
  343. package/dist/facts/FactSourceGroup.d.ts +26 -0
  344. package/dist/facts/FactTimelineViews.d.ts +37 -0
  345. package/dist/facts/FactsBulkBar.d.ts +53 -0
  346. package/dist/facts/FactsEmptyState.d.ts +38 -0
  347. package/dist/facts/FactsFieldsButton.d.ts +21 -0
  348. package/dist/facts/FactsFilterInput.d.ts +46 -0
  349. package/dist/facts/FactsTable.d.ts +28 -0
  350. package/dist/facts/FactsToolbar.d.ts +53 -0
  351. package/dist/facts/FactsViewToggle.d.ts +38 -0
  352. package/dist/facts/fact-date.d.ts +22 -0
  353. package/dist/facts/fact-row.d.ts +32 -0
  354. package/dist/facts/fact-text.d.ts +14 -0
  355. package/dist/facts/factColumns.d.ts +88 -0
  356. package/dist/facts/index.cjs +2401 -0
  357. package/dist/facts/index.cjs.map +1 -0
  358. package/dist/facts/index.d.ts +35 -0
  359. package/dist/facts/index.js +2343 -0
  360. package/dist/facts/index.js.map +1 -0
  361. package/dist/facts/timezone.d.ts +4 -0
  362. package/dist/files/AiReviewDialog.d.ts +77 -0
  363. package/dist/files/DocStatusIcon.d.ts +12 -0
  364. package/dist/files/DocumentGrid.d.ts +27 -0
  365. package/dist/files/Explorer.d.ts +10 -0
  366. package/dist/files/ExplorerSurface.d.ts +34 -0
  367. package/dist/files/ExplorerTile.d.ts +142 -0
  368. package/dist/files/ExportParts.d.ts +114 -0
  369. package/dist/files/FieldParts.d.ts +64 -0
  370. package/dist/files/FilesPage.d.ts +20 -0
  371. package/dist/files/FilesToolbar.d.ts +59 -0
  372. package/dist/files/FolderPicker.d.ts +82 -0
  373. package/dist/files/GridView.d.ts +59 -0
  374. package/dist/files/HtmlViewerParts.d.ts +183 -0
  375. package/dist/files/MoveToFolderDialog.d.ts +32 -0
  376. package/dist/files/RedlineParts.d.ts +72 -0
  377. package/dist/files/SelectionBar.d.ts +65 -0
  378. package/dist/files/StatusPill.d.ts +23 -0
  379. package/dist/files/TagPassagePanel.d.ts +60 -0
  380. package/dist/files/UploadDropzone.d.ts +33 -0
  381. package/dist/files/UploadFooter.d.ts +59 -0
  382. package/dist/files/UploadParts.d.ts +78 -0
  383. package/dist/files/UploadSources.d.ts +77 -0
  384. package/dist/files/VersionTimeline.d.ts +60 -0
  385. package/dist/files/ViewToggle.d.ts +53 -0
  386. package/dist/files/ViewerChrome.d.ts +152 -0
  387. package/dist/files/ViewerLayout.d.ts +32 -0
  388. package/dist/files/ViewerParts.d.ts +62 -0
  389. package/dist/files/bulk/BulkActionsBar.d.ts +76 -0
  390. package/dist/files/bulk/FolderFilterButton.d.ts +35 -0
  391. package/dist/files/bulk/index.d.ts +2 -0
  392. package/dist/files/cells/DocumentNameCell.d.ts +31 -0
  393. package/dist/files/cells/FolderCell.d.ts +25 -0
  394. package/dist/files/cells/HoverIconCell.d.ts +21 -0
  395. package/dist/files/cells/LabelMultiSelect.d.ts +50 -0
  396. package/dist/files/cells/RelatedDocsCell.d.ts +22 -0
  397. package/dist/files/cells/TagColumnParts.d.ts +29 -0
  398. package/dist/files/cells/index.d.ts +6 -0
  399. package/dist/files/documentGridLayout.d.ts +31 -0
  400. package/dist/files/grid-test-ids.d.ts +18 -0
  401. package/dist/files/import/CalendarImportRow.d.ts +26 -0
  402. package/dist/files/import/ImportParts.d.ts +114 -0
  403. package/dist/files/import/TaskSection.d.ts +51 -0
  404. package/dist/files/import/UrlInputDialogView.d.ts +63 -0
  405. package/dist/files/import/VendorLogo.d.ts +15 -0
  406. package/dist/files/import/index.d.ts +5 -0
  407. package/dist/files/index.cjs +7555 -0
  408. package/dist/files/index.cjs.map +1 -0
  409. package/dist/files/index.d.ts +34 -0
  410. package/dist/files/index.js +7340 -0
  411. package/dist/files/index.js.map +1 -0
  412. package/dist/files/page/FilesAddMenu.d.ts +30 -0
  413. package/dist/files/page/FilesPageParts.d.ts +24 -0
  414. package/dist/files/page/FilesPageTitle.d.ts +24 -0
  415. package/dist/files/page/index.d.ts +3 -0
  416. package/dist/files/tags/BulkTagEditor.d.ts +136 -0
  417. package/dist/files/tags/DocTagPopover.d.ts +113 -0
  418. package/dist/files/tags/TagManager.d.ts +54 -0
  419. package/dist/files/tags/index.d.ts +3 -0
  420. package/dist/files/views/FieldsEditorParts.d.ts +151 -0
  421. package/dist/files/views/FieldsManagerParts.d.ts +17 -0
  422. package/dist/files/views/TagFormParts.d.ts +109 -0
  423. package/dist/files/views/ViewSelectorMenu.d.ts +66 -0
  424. package/dist/files/views/fieldsEditorModel.d.ts +43 -0
  425. package/dist/files/views/index.d.ts +5 -0
  426. package/dist/home/ActionMenuDialog.d.ts +26 -0
  427. package/dist/home/AddFilesFirst.d.ts +22 -0
  428. package/dist/home/CardHeaderBar.d.ts +40 -0
  429. package/dist/home/CollapsibleSection.d.ts +43 -0
  430. package/dist/home/CreateTile.d.ts +17 -0
  431. package/dist/home/DashboardParts.d.ts +32 -0
  432. package/dist/home/FactsStrip.d.ts +41 -0
  433. package/dist/home/FoldSection.d.ts +19 -0
  434. package/dist/home/GettingStartedStrip.d.ts +49 -0
  435. package/dist/home/Greeting.d.ts +18 -0
  436. package/dist/home/HomeLayout.d.ts +28 -0
  437. package/dist/home/KeyValueRow.d.ts +43 -0
  438. package/dist/home/ProjectBandParts.d.ts +70 -0
  439. package/dist/home/QuickActionDialogHeader.d.ts +21 -0
  440. package/dist/home/RecentList.d.ts +48 -0
  441. package/dist/home/ScopePicker.d.ts +65 -0
  442. package/dist/home/StartTiles.d.ts +33 -0
  443. package/dist/home/index.cjs +854 -0
  444. package/dist/home/index.cjs.map +1 -0
  445. package/dist/home/index.d.ts +37 -0
  446. package/dist/home/index.js +763 -0
  447. package/dist/home/index.js.map +1 -0
  448. package/dist/home/sections.d.ts +33 -0
  449. package/dist/index.cjs +1992 -5547
  450. package/dist/index.cjs.map +1 -1
  451. package/dist/index.d.ts +72 -1716
  452. package/dist/index.js +142 -5316
  453. package/dist/index.js.map +1 -1
  454. package/dist/lib/balanced-columns.d.ts +8 -0
  455. package/dist/lib/format.d.ts +37 -0
  456. package/dist/lib/observe-resize.d.ts +6 -0
  457. package/dist/lib/password-strength.d.ts +24 -0
  458. package/dist/lib/sidebar-mode.d.ts +46 -0
  459. package/dist/lib/testid.d.ts +7 -0
  460. package/dist/lib/use-drawer.d.ts +11 -0
  461. package/dist/lib/useControllableState.d.ts +5 -0
  462. package/dist/lib/useDismissibleCard.d.ts +15 -0
  463. package/dist/lib/useListKeyNav.d.ts +42 -0
  464. package/dist/lib/useLongPaste.d.ts +15 -0
  465. package/dist/lib/useRestoreFocus.d.ts +11 -0
  466. package/dist/lib/useScopeSelection.d.ts +34 -0
  467. package/dist/nav/types.d.ts +19 -0
  468. package/dist/provider/BlocksProvider.d.ts +20 -0
  469. package/dist/provider/TooltipScope.d.ts +9 -0
  470. package/dist/record/index.cjs +2 -4
  471. package/dist/record/index.cjs.map +1 -1
  472. package/dist/record/index.d.ts +12 -16
  473. package/dist/record/index.js +2 -4
  474. package/dist/record/index.js.map +1 -1
  475. package/dist/retrieval/HighlightText.d.ts +21 -0
  476. package/dist/retrieval/SearchEmptyState.d.ts +39 -0
  477. package/dist/retrieval/SearchGroupHeader.d.ts +21 -0
  478. package/dist/retrieval/SearchHit.d.ts +36 -0
  479. package/dist/retrieval/SearchPage.d.ts +187 -0
  480. package/dist/retrieval/SearchPagination.d.ts +21 -0
  481. package/dist/retrieval/highlight.d.ts +21 -0
  482. package/dist/retrieval/index.cjs +160 -0
  483. package/dist/retrieval/index.cjs.map +1 -0
  484. package/dist/retrieval/index.d.ts +7 -0
  485. package/dist/retrieval/index.js +7 -0
  486. package/dist/retrieval/index.js.map +1 -0
  487. package/dist/settings/AccountDialogs.d.ts +89 -0
  488. package/dist/settings/AvatarPicker.d.ts +25 -0
  489. package/dist/settings/Billing.d.ts +113 -0
  490. package/dist/settings/ConfigSwitcherBar.d.ts +46 -0
  491. package/dist/settings/ConfirmDialog.d.ts +28 -0
  492. package/dist/settings/ConnectionCard.d.ts +58 -0
  493. package/dist/settings/ConversationSettingsParts.d.ts +53 -0
  494. package/dist/settings/DocumentPicker.d.ts +57 -0
  495. package/dist/settings/EmailWorkspaceDialogView.d.ts +60 -0
  496. package/dist/settings/ErrorDialog.d.ts +36 -0
  497. package/dist/settings/FloatingPanel.d.ts +32 -0
  498. package/dist/settings/JsonTree.d.ts +24 -0
  499. package/dist/settings/LogoutDialog.d.ts +51 -0
  500. package/dist/settings/ModalBreadcrumbHeader.d.ts +32 -0
  501. package/dist/settings/ModalScaffold.d.ts +60 -0
  502. package/dist/settings/MultiSelect.d.ts +111 -0
  503. package/dist/settings/NotificationCategoryList.d.ts +26 -0
  504. package/dist/settings/PanelFrame.d.ts +47 -0
  505. package/dist/settings/PasswordChangeDialog.d.ts +64 -0
  506. package/dist/settings/PlanBadge.d.ts +14 -0
  507. package/dist/settings/PlanCard.d.ts +97 -0
  508. package/dist/settings/PremiumModelsFrame.d.ts +17 -0
  509. package/dist/settings/ProfileCard.d.ts +67 -0
  510. package/dist/settings/Projects.d.ts +108 -0
  511. package/dist/settings/QuotaMeter.d.ts +31 -0
  512. package/dist/settings/ReferralCredit.d.ts +46 -0
  513. package/dist/settings/SegmentedControl.d.ts +20 -0
  514. package/dist/settings/ServerConnectionControls.d.ts +31 -0
  515. package/dist/settings/SettingsPanel.d.ts +61 -0
  516. package/dist/settings/SettingsSwitchRow.d.ts +21 -0
  517. package/dist/settings/SubscriptionParts.d.ts +215 -0
  518. package/dist/settings/SupportPanel.d.ts +32 -0
  519. package/dist/settings/SyncDialogParts.d.ts +155 -0
  520. package/dist/settings/ThreadPreviewDialog.d.ts +18 -0
  521. package/dist/settings/TipsEditorDialog.d.ts +94 -0
  522. package/dist/settings/TriStateFilterMenu.d.ts +66 -0
  523. package/dist/settings/Usage.d.ts +102 -0
  524. package/dist/settings/WelcomeDialog.d.ts +79 -0
  525. package/dist/settings/index.cjs +5131 -0
  526. package/dist/settings/index.cjs.map +1 -0
  527. package/dist/settings/index.d.ts +38 -0
  528. package/dist/settings/index.js +4922 -0
  529. package/dist/settings/index.js.map +1 -0
  530. package/dist/shell/ActionCluster.d.ts +33 -0
  531. package/dist/shell/AskField.d.ts +76 -0
  532. package/dist/shell/InfoBar.d.ts +20 -0
  533. package/dist/shell/MobileBars.d.ts +47 -0
  534. package/dist/shell/OfflinePill.d.ts +28 -0
  535. package/dist/shell/RemoteControlPill.d.ts +23 -0
  536. package/dist/shell/Shell.d.ts +123 -0
  537. package/dist/shell/Sidebar.d.ts +104 -0
  538. package/dist/shell/SidebarBadgeRow.d.ts +29 -0
  539. package/dist/shell/SidebarRowAction.d.ts +24 -0
  540. package/dist/shell/StatusRow.d.ts +20 -0
  541. package/dist/shell/TabHeader.d.ts +70 -0
  542. package/dist/shell/TipCard.d.ts +46 -0
  543. package/dist/shell/ToolButton.d.ts +12 -0
  544. package/dist/shell/Workspace.d.ts +90 -0
  545. package/dist/shell/index.cjs +187 -0
  546. package/dist/shell/index.cjs.map +1 -0
  547. package/dist/shell/index.d.ts +20 -0
  548. package/dist/shell/index.js +10 -0
  549. package/dist/shell/index.js.map +1 -0
  550. package/dist/shell/sidebar-context.d.ts +19 -0
  551. package/dist/shell/types.d.ts +48 -0
  552. package/dist/site/index.cjs +173 -90
  553. package/dist/site/index.d.ts +60 -4
  554. package/dist/site/index.js +8 -1
  555. package/dist/studio/PageRenderer.d.ts +35 -0
  556. package/dist/studio/Section.d.ts +24 -0
  557. package/dist/studio/StudioEditor.d.ts +32 -0
  558. package/dist/studio/aiFields.d.ts +17 -0
  559. package/dist/studio/blockKit.d.ts +36 -0
  560. package/dist/studio/blocksConfig.d.ts +42 -0
  561. package/dist/studio/imageFields.d.ts +14 -0
  562. package/dist/studio/index.cjs +3353 -0
  563. package/dist/studio/index.cjs.map +1 -0
  564. package/dist/studio/index.d.ts +32 -0
  565. package/dist/studio/index.js +3297 -0
  566. package/dist/studio/index.js.map +1 -0
  567. package/dist/studio/liveData.d.ts +4 -0
  568. package/dist/studio/liveWidgetRuntime.d.ts +41 -0
  569. package/dist/studio/persistence.d.ts +38 -0
  570. package/dist/studio/publish.d.ts +39 -0
  571. package/dist/studio/siteBlocks.d.ts +14 -0
  572. package/dist/studio/types.d.ts +46 -0
  573. package/dist/studio/websiteBlocks.d.ts +4 -0
  574. package/dist/studio/widgets.d.ts +20 -0
  575. package/dist/theme/ThemeEditor.d.ts +16 -0
  576. package/dist/theme/fontPairings.d.ts +48 -0
  577. package/dist/theme/store.d.ts +53 -0
  578. package/dist/theme/tokens.d.ts +105 -0
  579. package/dist/timeline/Timeline.d.ts +27 -0
  580. package/dist/timeline/TimelineCalendar.d.ts +54 -0
  581. package/dist/timeline/TimelineGantt.d.ts +71 -0
  582. package/dist/timeline/TimelineZoomControl.d.ts +17 -0
  583. package/dist/timeline/index.cjs +50 -0
  584. package/dist/timeline/index.cjs.map +1 -0
  585. package/dist/timeline/index.d.ts +13 -0
  586. package/dist/timeline/index.js +5 -0
  587. package/dist/timeline/index.js.map +1 -0
  588. package/dist/timeline/span.d.ts +29 -0
  589. package/dist/timeline/types.d.ts +30 -0
  590. package/dist/workspaces/WorkspaceBadges.d.ts +27 -0
  591. package/dist/workspaces/WorkspaceCard.d.ts +142 -0
  592. package/dist/workspaces/WorkspaceFormParts.d.ts +98 -0
  593. package/dist/workspaces/WorkspaceGroup.d.ts +31 -0
  594. package/dist/workspaces/WorkspaceSettingsParts.d.ts +70 -0
  595. package/dist/workspaces/index.cjs +690 -0
  596. package/dist/workspaces/index.cjs.map +1 -0
  597. package/dist/workspaces/index.d.ts +9 -0
  598. package/dist/workspaces/index.js +661 -0
  599. package/dist/workspaces/index.js.map +1 -0
  600. package/package.json +154 -9
  601. package/src/blocks.css +365 -0
  602. package/src/components/grid.css +60 -107
  603. package/src/source.css +20 -0
  604. package/src/studio/studio.css +3 -3
  605. package/src/tokens.css +226 -0
  606. package/dist/chunk-DBAUZD7A.cjs.map +0 -1
  607. package/dist/chunk-FZ2S6VAZ.js.map +0 -1
  608. package/dist/index-DduoEosi.d.cts +0 -846
  609. package/dist/index-DduoEosi.d.ts +0 -846
  610. package/dist/index.d.cts +0 -1717
  611. package/dist/record/index.d.cts +0 -96
  612. package/dist/site/index.d.cts +0 -4
@@ -1,12 +1,34 @@
1
+ "use client";
1
2
  'use strict';
2
3
 
4
+ var chunkWJMEXTVD_cjs = require('./chunk-WJMEXTVD.cjs');
3
5
  var zustand = require('zustand');
4
6
  var middleware = require('zustand/middleware');
5
7
  var react = require('react');
6
8
  var lucideReact = require('lucide-react');
7
9
  var ui = require('@arbidocs/react/ui');
8
10
  var jsxRuntime = require('react/jsx-runtime');
9
- var reactDom = require('react-dom');
11
+ var TabsPrimitive = require('@radix-ui/react-tabs');
12
+
13
+ function _interopNamespace(e) {
14
+ if (e && e.__esModule) return e;
15
+ var n = Object.create(null);
16
+ if (e) {
17
+ Object.keys(e).forEach(function (k) {
18
+ if (k !== 'default') {
19
+ var d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: function () { return e[k]; }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+
31
+ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
10
32
 
11
33
  // src/theme/tokens.ts
12
34
  var THEME_STYLE_ID = "arbi-theme-vars";
@@ -246,110 +268,6 @@ function applyStoredTheme(bundle) {
246
268
  const { colors, fonts, radius } = bundle.useStore.getState();
247
269
  applyThemeVars({ colors, fonts, radius }, { mode: bundle.mode, dark: bundle.darkColors });
248
270
  }
249
-
250
- // src/lib/format.ts
251
- function gbp(value, compact = false) {
252
- return new Intl.NumberFormat("en-GB", {
253
- style: "currency",
254
- currency: "GBP",
255
- maximumFractionDigits: compact && Math.abs(value) >= 1e3 ? 1 : 0,
256
- notation: compact ? "compact" : "standard"
257
- }).format(value);
258
- }
259
- function initials(name) {
260
- const parts = name.trim().split(/\s+/);
261
- if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
262
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
263
- }
264
- function parseIso(iso) {
265
- const dateOnly = /^\d{4}-\d{2}-\d{2}$/.test(iso);
266
- const d = new Date(dateOnly ? `${iso}T00:00:00` : iso);
267
- if (Number.isNaN(d.getTime())) throw new Error(`Invalid ISO date: ${iso}`);
268
- return d;
269
- }
270
- function fmtDate(iso) {
271
- try {
272
- return new Intl.DateTimeFormat("en-GB", {
273
- day: "numeric",
274
- month: "short",
275
- year: "numeric"
276
- }).format(parseIso(iso));
277
- } catch {
278
- return iso;
279
- }
280
- }
281
- function fmtDateTime(iso) {
282
- try {
283
- return new Intl.DateTimeFormat("en-GB", {
284
- day: "numeric",
285
- month: "short",
286
- year: "numeric",
287
- hour: "2-digit",
288
- minute: "2-digit",
289
- hour12: false
290
- }).format(parseIso(iso));
291
- } catch {
292
- return iso;
293
- }
294
- }
295
- var RELATIVE_UNITS = [
296
- ["year", 31536e3],
297
- ["month", 2592e3],
298
- ["week", 604800],
299
- ["day", 86400],
300
- ["hour", 3600],
301
- ["minute", 60],
302
- ["second", 1]
303
- ];
304
- function fromNow(iso, from = /* @__PURE__ */ new Date()) {
305
- try {
306
- const diffSeconds = (parseIso(iso).getTime() - from.getTime()) / 1e3;
307
- const abs = Math.abs(diffSeconds);
308
- const rtf = new Intl.RelativeTimeFormat("en-GB", { numeric: "always" });
309
- for (const [unit, secs] of RELATIVE_UNITS) {
310
- if (abs >= secs || unit === "second") {
311
- const value = Math.round(diffSeconds / secs);
312
- return rtf.format(value, unit);
313
- }
314
- }
315
- return rtf.format(0, "second");
316
- } catch {
317
- return iso;
318
- }
319
- }
320
- function daysUntil(iso, from = /* @__PURE__ */ new Date()) {
321
- try {
322
- const target = parseIso(iso);
323
- const a = Date.UTC(target.getFullYear(), target.getMonth(), target.getDate());
324
- const b = Date.UTC(from.getFullYear(), from.getMonth(), from.getDate());
325
- return Math.round((a - b) / 864e5);
326
- } catch {
327
- return 0;
328
- }
329
- }
330
- function hrs(n) {
331
- return `${n.toFixed(1)}h`;
332
- }
333
- function pct(n) {
334
- return `${Math.round(n)}%`;
335
- }
336
- function formatPageRefs(pages) {
337
- const sorted = [...new Set(pages)].sort((a, b) => a - b);
338
- if (sorted.length === 0) return "";
339
- const parts = [];
340
- let start = sorted[0];
341
- let end = sorted[0];
342
- for (const page of sorted.slice(1)) {
343
- if (page === end + 1) {
344
- end = page;
345
- continue;
346
- }
347
- parts.push(start === end ? `${start}` : `${start}\u2013${end}`);
348
- start = end = page;
349
- }
350
- parts.push(start === end ? `${start}` : `${start}\u2013${end}`);
351
- return `${sorted.length === 1 ? "p" : "pp"} ${parts.join(", ")}`;
352
- }
353
271
  function ThemeEditor({
354
272
  bundle,
355
273
  variant = "panel",
@@ -378,9 +296,14 @@ function ThemeEditor({
378
296
  const save = async () => {
379
297
  if (!onSave) return;
380
298
  setSaving(true);
381
- const via = await onSave();
382
- setSavedVia(typeof via === "string" ? via : "saved");
383
- setSaving(false);
299
+ try {
300
+ const via = await onSave();
301
+ setSavedVia(typeof via === "string" ? via : "saved");
302
+ } catch {
303
+ setSavedVia(null);
304
+ } finally {
305
+ setSaving(false);
306
+ }
384
307
  };
385
308
  const Presets = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
386
309
  presets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -427,7 +350,7 @@ function ThemeEditor({
427
350
  {
428
351
  value: colors[k] ?? "",
429
352
  onChange: (e) => setColor(k, e.target.value),
430
- className: "bg-card placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50 h-7 font-mono text-xs",
353
+ className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring h-7 font-mono text-xs",
431
354
  "data-testid": tid2(`hex-${k}`)
432
355
  }
433
356
  )
@@ -442,7 +365,7 @@ function ThemeEditor({
442
365
  {
443
366
  value: activePairing?.id ?? "",
444
367
  onChange: (e) => setFontPairing(e.target.value),
445
- className: "mt-1 h-8 w-full rounded-md border border-border bg-card px-2 text-xs text-foreground focus-visible:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50",
368
+ className: "mt-1 h-8 w-full rounded-md border border-border bg-card px-2 text-xs text-foreground focus-visible:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
446
369
  "data-testid": tid2("font-pairing"),
447
370
  children: [
448
371
  !activePairing && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Custom" }),
@@ -450,7 +373,7 @@ function ThemeEditor({
450
373
  ]
451
374
  }
452
375
  ),
453
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-[11px] text-muted-foreground", children: activePairing?.description ?? "Hand-edited font stacks." })
376
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: activePairing?.description ?? "Hand-edited font stacks." })
454
377
  ] }),
455
378
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
456
379
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: "Display font stack" }),
@@ -459,7 +382,7 @@ function ThemeEditor({
459
382
  {
460
383
  value: fonts.display,
461
384
  onChange: (e) => setFont("display", e.target.value),
462
- className: "bg-card placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50 mt-1 font-mono text-xs",
385
+ className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs",
463
386
  "data-testid": tid2("font-display")
464
387
  }
465
388
  )
@@ -471,7 +394,7 @@ function ThemeEditor({
471
394
  {
472
395
  value: fonts.sans,
473
396
  onChange: (e) => setFont("sans", e.target.value),
474
- className: "bg-card placeholder:text-muted-foreground/70 focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring/50 mt-1 font-mono text-xs",
397
+ className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs",
475
398
  "data-testid": tid2("font-sans")
476
399
  }
477
400
  )
@@ -497,7 +420,7 @@ function ThemeEditor({
497
420
  )
498
421
  ] })
499
422
  ] });
500
- const Preview = /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-xl", "data-testid": tid2("preview"), children: [
423
+ const Preview = /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-lg", "data-testid": tid2("preview"), children: [
501
424
  /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.CardTitle, { className: "text-base", children: "Live preview" }) }),
502
425
  /* @__PURE__ */ jsxRuntime.jsxs(ui.CardContent, { className: "space-y-3", children: [
503
426
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-[var(--radius)] bg-primary p-4 text-primary-foreground", children: [
@@ -543,16 +466,16 @@ function ThemeEditor({
543
466
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-y-auto bg-card p-5", "data-testid": testIdPrefix, children: [
544
467
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-display text-lg font-semibold text-foreground", children: "Theme" }) }),
545
468
  Presets,
546
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-5 mb-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
469
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-5 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
547
470
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: tokens.map((t) => colorRow(t.key, t.label)) }),
548
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-6 mb-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
471
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
549
472
  Typography,
550
473
  SaveBar
551
474
  ] });
552
475
  }
553
476
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 lg:grid-cols-[1fr_320px]", "data-testid": testIdPrefix, children: [
554
477
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
555
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-xl", children: [
478
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-lg", children: [
556
479
  /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.CardTitle, { className: "flex items-center gap-2 text-base", children: [
557
480
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: "size-4 text-[color:var(--color-primary)]" }),
558
481
  " Presets"
@@ -563,7 +486,7 @@ function ThemeEditor({
563
486
  ui.Card,
564
487
  {
565
488
  variant: "elevated",
566
- className: "rounded-xl",
489
+ className: "rounded-lg",
567
490
  "data-testid": tid2(`group-${group}`),
568
491
  children: [
569
492
  /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.CardTitle, { className: "text-base", children: groupLabels[group] ?? group }) }),
@@ -572,7 +495,7 @@ function ThemeEditor({
572
495
  },
573
496
  group
574
497
  )),
575
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-xl", children: [
498
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-lg", children: [
576
499
  /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.CardTitle, { className: "text-base", children: "Typography & shape" }) }),
577
500
  /* @__PURE__ */ jsxRuntime.jsx(ui.CardContent, { children: Typography })
578
501
  ] }),
@@ -588,854 +511,6 @@ function tid(...parts) {
588
511
  (p) => String(p).trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")
589
512
  ).join("-");
590
513
  }
591
-
592
- // src/timeline/span.ts
593
- var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
594
- var MONTH_NAMES = [
595
- "January",
596
- "February",
597
- "March",
598
- "April",
599
- "May",
600
- "June",
601
- "July",
602
- "August",
603
- "September",
604
- "October",
605
- "November",
606
- "December"
607
- ];
608
- var WEEKDAY_NAMES = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
609
- var DAY_MS = 864e5;
610
- function monthLabel(d) {
611
- return `${MONTH_NAMES[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
612
- }
613
- function utcDay(d) {
614
- return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
615
- }
616
- function dayKey(d) {
617
- return d.toISOString().slice(0, 10);
618
- }
619
- function parseIso2(iso) {
620
- if (!iso) return null;
621
- const d = new Date(iso);
622
- return isNaN(d.getTime()) ? null : d;
623
- }
624
- function isMidnight(d) {
625
- return d.getUTCHours() === 0 && d.getUTCMinutes() === 0 && d.getUTCSeconds() === 0;
626
- }
627
- function isEndOfDay(d) {
628
- return d.getUTCHours() === 23 && d.getUTCMinutes() === 59;
629
- }
630
- function lastDayOfMonth(d) {
631
- return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 0)).getUTCDate();
632
- }
633
- function day(d) {
634
- return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
635
- }
636
- function zonedDayAndTime(d, timeZone) {
637
- const parts = Object.fromEntries(
638
- new Intl.DateTimeFormat("en-US", {
639
- timeZone,
640
- hourCycle: "h23",
641
- year: "numeric",
642
- month: "short",
643
- day: "numeric",
644
- hour: "2-digit",
645
- minute: "2-digit"
646
- }).formatToParts(d).map((p) => [p.type, p.value])
647
- );
648
- return { day: `${parts.day} ${parts.month} ${parts.year}`, hh: parts.hour, mm: parts.minute };
649
- }
650
- function formatSpan(startIso, endIso, timezone) {
651
- if (!startIso) return "";
652
- const start = new Date(startIso);
653
- const end = endIso ? new Date(endIso) : start;
654
- if (startIso === endIso) {
655
- if (timezone) {
656
- try {
657
- const zoned = zonedDayAndTime(start, timezone);
658
- return `${zoned.day}, ${zoned.hh}:${zoned.mm} ${timezone}`;
659
- } catch {
660
- }
661
- }
662
- const hh = String(start.getUTCHours()).padStart(2, "0");
663
- const mm = String(start.getUTCMinutes()).padStart(2, "0");
664
- return `${day(start)}, ${hh}:${mm} UTC`;
665
- }
666
- if (isMidnight(start) && isEndOfDay(end)) {
667
- const sameDay = start.getUTCFullYear() === end.getUTCFullYear() && start.getUTCMonth() === end.getUTCMonth() && start.getUTCDate() === end.getUTCDate();
668
- if (sameDay) return day(start);
669
- const firstOfMonth = start.getUTCDate() === 1;
670
- const endsMonth = end.getUTCDate() === lastDayOfMonth(end);
671
- const sameMonth = start.getUTCFullYear() === end.getUTCFullYear() && start.getUTCMonth() === end.getUTCMonth();
672
- if (firstOfMonth && endsMonth && sameMonth) {
673
- return `${MONTHS[start.getUTCMonth()]} ${start.getUTCFullYear()}`;
674
- }
675
- const wholeYear = firstOfMonth && endsMonth && start.getUTCMonth() === 0 && end.getUTCMonth() === 11 && start.getUTCFullYear() === end.getUTCFullYear();
676
- if (wholeYear) return String(start.getUTCFullYear());
677
- return `${day(start)} \u2013 ${day(end)}`;
678
- }
679
- return `${day(start)} \u2013 ${day(end)}`;
680
- }
681
- var DEFAULT_MAX_LANES = 3;
682
- var MAX_WEEKS = 2600;
683
- function TimelineCalendar({
684
- items,
685
- onSelect,
686
- selectedIds,
687
- maxLanes = DEFAULT_MAX_LANES,
688
- navigatorContainer,
689
- navigatorTotal,
690
- emptyState,
691
- className,
692
- testId = "timeline-calendar"
693
- }) {
694
- const dated = react.useMemo(() => items.filter((i) => i.start), [items]);
695
- const sortedItems = react.useMemo(
696
- () => [...dated].sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()),
697
- [dated]
698
- );
699
- const indexById = react.useMemo(() => new Map(sortedItems.map((it, i) => [it.id, i])), [sortedItems]);
700
- const [activeIndex, setActiveIndex] = react.useState(null);
701
- const scrollRef = react.useRef(null);
702
- const select = react.useCallback(
703
- (index) => {
704
- const clamped = Math.max(0, Math.min(sortedItems.length - 1, index));
705
- setActiveIndex(clamped);
706
- onSelect?.(sortedItems[clamped]);
707
- return clamped;
708
- },
709
- [onSelect, sortedItems]
710
- );
711
- const scrollToItem = react.useCallback(
712
- (id, behavior) => {
713
- scrollRef.current?.querySelector(`[data-testid="${testId}-entry-${id}"]`)?.scrollIntoView({ block: "center", behavior });
714
- },
715
- [testId]
716
- );
717
- const lastNavScrollRef = react.useRef(null);
718
- const goTo = react.useCallback(
719
- (index) => {
720
- const target = sortedItems[select(index)];
721
- if (target) {
722
- lastNavScrollRef.current = target.id;
723
- scrollToItem(target.id, "smooth");
724
- }
725
- },
726
- [select, sortedItems, scrollToItem]
727
- );
728
- const selectedKey = (selectedIds ?? []).join("\0");
729
- react.useEffect(() => {
730
- const id = selectedKey ? selectedKey.split("\0")[0] : null;
731
- if (!id) return;
732
- if (lastNavScrollRef.current === id) {
733
- lastNavScrollRef.current = null;
734
- return;
735
- }
736
- scrollToItem(id, "auto");
737
- }, [selectedKey, scrollToItem]);
738
- const weeks = react.useMemo(() => {
739
- if (dated.length === 0) return [];
740
- const times = dated.flatMap((i) => [
741
- new Date(i.start).getTime(),
742
- new Date(i.end ?? i.start).getTime()
743
- ]);
744
- const first = utcDay(new Date(Math.min(...times)));
745
- const last = utcDay(new Date(Math.max(...times)));
746
- const gridStart = new Date(first);
747
- gridStart.setUTCDate(first.getUTCDate() - (first.getUTCDay() + 6) % 7);
748
- const out = [];
749
- const cursor = new Date(gridStart);
750
- while (cursor <= last && out.length < MAX_WEEKS) {
751
- out.push(
752
- Array.from({ length: 7 }, (_, d) => {
753
- const day2 = new Date(cursor);
754
- day2.setUTCDate(cursor.getUTCDate() + d);
755
- return day2;
756
- })
757
- );
758
- cursor.setUTCDate(cursor.getUTCDate() + 7);
759
- }
760
- return out;
761
- }, [dated]);
762
- const segmentsByWeek = react.useMemo(() => {
763
- if (weeks.length === 0) return [];
764
- const gridStartMs = weeks[0][0].getTime();
765
- const WEEK_MS2 = 7 * DAY_MS;
766
- const ranged = dated.map((item) => ({
767
- item,
768
- start: utcDay(new Date(item.start)),
769
- end: utcDay(new Date(item.end ?? item.start))
770
- }));
771
- ranged.sort((a, b) => {
772
- const lenA = b.end.getTime() - b.start.getTime();
773
- const lenB = a.end.getTime() - a.start.getTime();
774
- return lenA - lenB || a.start.getTime() - b.start.getTime();
775
- });
776
- const buckets = weeks.map(() => []);
777
- for (const r of ranged) {
778
- const from = Math.max(0, Math.floor((r.start.getTime() - gridStartMs) / WEEK_MS2));
779
- const to = Math.min(weeks.length - 1, Math.floor((r.end.getTime() - gridStartMs) / WEEK_MS2));
780
- for (let w = from; w <= to; w++) buckets[w].push(r);
781
- }
782
- return weeks.map((week, wi) => {
783
- const weekStart = week[0];
784
- const weekEnd = week[6];
785
- const laneEnds = [];
786
- const segments = [];
787
- let overflow = 0;
788
- for (const { item, start, end } of buckets[wi]) {
789
- const from = start < weekStart ? weekStart : start;
790
- const to = end > weekEnd ? weekEnd : end;
791
- const startCol = Math.round((from.getTime() - weekStart.getTime()) / DAY_MS);
792
- const endCol = Math.round((to.getTime() - weekStart.getTime()) / DAY_MS);
793
- let lane = laneEnds.findIndex((last) => last < startCol);
794
- if (lane === -1) lane = laneEnds.length;
795
- if (lane >= maxLanes) {
796
- overflow += 1;
797
- continue;
798
- }
799
- laneEnds[lane] = endCol;
800
- segments.push({
801
- item,
802
- startCol,
803
- span: endCol - startCol + 1,
804
- isStart: start >= weekStart,
805
- isEnd: end <= weekEnd,
806
- lane
807
- });
808
- }
809
- return { segments, overflow };
810
- });
811
- }, [weeks, dated, maxLanes]);
812
- if (weeks.length === 0 && emptyState) {
813
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: emptyState });
814
- }
815
- const selectedSet = new Set(selectedIds ?? []);
816
- const selectedIndex = sortedItems.findIndex((i) => selectedSet.has(i.id));
817
- const currentIndex = selectedIndex >= 0 ? selectedIndex : activeIndex;
818
- const navigator = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-0.5", "data-testid": `${testId}-nav`, children: [
819
- /* @__PURE__ */ jsxRuntime.jsx(
820
- "button",
821
- {
822
- type: "button",
823
- "aria-label": "Previous event",
824
- "data-testid": `${testId}-nav-prev`,
825
- disabled: sortedItems.length === 0 || currentIndex === null || currentIndex <= 0,
826
- onClick: () => goTo((currentIndex ?? 0) - 1),
827
- className: "rounded p-0.5 text-muted-foreground enabled:hover:bg-accent enabled:hover:text-foreground disabled:opacity-30",
828
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
829
- }
830
- ),
831
- /* @__PURE__ */ jsxRuntime.jsxs(
832
- "span",
833
- {
834
- className: "tabular-nums text-sm font-light text-muted-foreground",
835
- "data-testid": `${testId}-nav-position`,
836
- children: [
837
- currentIndex !== null ? currentIndex + 1 : "\u2013",
838
- " /",
839
- " ",
840
- navigatorTotal ?? (sortedItems.length > 0 ? sortedItems.length : "\u2013")
841
- ]
842
- }
843
- ),
844
- /* @__PURE__ */ jsxRuntime.jsx(
845
- "button",
846
- {
847
- type: "button",
848
- "aria-label": "Next event",
849
- "data-testid": `${testId}-nav-next`,
850
- disabled: sortedItems.length === 0 || currentIndex !== null && currentIndex >= sortedItems.length - 1,
851
- onClick: () => goTo(currentIndex === null ? 0 : currentIndex + 1),
852
- className: "rounded p-0.5 text-muted-foreground enabled:hover:bg-accent enabled:hover:text-foreground disabled:opacity-30",
853
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
854
- }
855
- )
856
- ] });
857
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex flex-col h-full", className), "data-testid": testId, children: [
858
- navigatorContainer === void 0 ? navigator && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center justify-end border-b border-border px-2 py-1", children: navigator }) : navigatorContainer && navigator && reactDom.createPortal(navigator, navigatorContainer),
859
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 border-b border-border bg-background", children: WEEKDAY_NAMES.map((d) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1 text-[11px] text-muted-foreground text-center", children: d }, d)) }),
860
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex-1 overflow-auto", "data-testid": `${testId}-scroll`, children: weeks.map((week, wi) => {
861
- const { segments, overflow } = segmentsByWeek[wi];
862
- const monthStartDay = week.find((d) => d.getUTCDate() === 1);
863
- const marker = monthStartDay ?? (wi === 0 ? week[0] : void 0);
864
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
865
- marker && // Sticky, so the month you are LOOKING at names itself: it
866
- // pins to the top of the scroller while you are inside it and
867
- // is pushed up by the next one. No scroll listener needed.
868
- /* @__PURE__ */ jsxRuntime.jsx(
869
- "div",
870
- {
871
- className: "sticky top-0 z-10 px-3 py-1 text-xs font-medium text-foreground bg-background/95 backdrop-blur border-y border-border/60",
872
- "data-testid": `${testId}-month-${marker.getUTCFullYear()}-${String(
873
- marker.getUTCMonth() + 1
874
- ).padStart(2, "0")}`,
875
- children: monthLabel(marker)
876
- }
877
- ),
878
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border/40", children: [
879
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 bg-background", children: week.map((day2) => /* @__PURE__ */ jsxRuntime.jsx(
880
- "div",
881
- {
882
- "data-testid": `${testId}-day-${dayKey(day2)}`,
883
- className: ui.cn(
884
- "px-1 pt-1 text-[11px] border-r border-border/40",
885
- day2.getUTCDate() === 1 ? "text-foreground font-medium" : "text-muted-foreground/60"
886
- ),
887
- children: day2.getUTCDate()
888
- },
889
- dayKey(day2)
890
- )) }),
891
- /* @__PURE__ */ jsxRuntime.jsxs(
892
- "div",
893
- {
894
- className: "grid grid-cols-7 gap-y-0.5 px-0.5 pb-1 bg-muted/40",
895
- style: { gridAutoRows: "18px", minHeight: 62 },
896
- children: [
897
- segments.map((seg) => /* @__PURE__ */ jsxRuntime.jsx(
898
- "button",
899
- {
900
- type: "button",
901
- onClick: () => select(indexById.get(seg.item.id) ?? 0),
902
- title: `${formatSpan(seg.item.start, seg.item.end)} \u2014 ${seg.item.label}`,
903
- "data-testid": `${testId}-entry-${seg.item.id}`,
904
- style: {
905
- gridColumn: `${seg.startCol + 1} / span ${seg.span}`,
906
- gridRow: seg.lane + 1
907
- },
908
- className: ui.cn(
909
- // One line per event (truncated), so several events stack
910
- // compactly on the same day instead of a few tall bars
911
- // pushing the rest into a "+n more". Every event is the
912
- // SAME neutral colour; the one open in the composer is
913
- // marked by the caller (a ring), not by a different fill.
914
- "block h-full w-full truncate text-left text-[10px] leading-[14px] py-[1px] px-1",
915
- "bg-muted text-muted-foreground",
916
- seg.isStart && "rounded-l",
917
- seg.isEnd && "rounded-r"
918
- ),
919
- children: seg.isStart ? seg.item.label : " "
920
- },
921
- `${seg.item.id}-${seg.startCol}`
922
- )),
923
- overflow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
924
- "span",
925
- {
926
- className: "text-[10px] text-muted-foreground px-1",
927
- style: { gridColumn: "1 / span 7", gridRow: maxLanes + 1 },
928
- children: [
929
- "+",
930
- overflow,
931
- " more"
932
- ]
933
- }
934
- )
935
- ]
936
- }
937
- )
938
- ] })
939
- ] }, dayKey(week[0]));
940
- }) })
941
- ] });
942
- }
943
- var TIMELINE_ZOOM = { MIN: 1, MAX: 10, STEP: 0.25 };
944
- function TimelineZoomControl({
945
- zoom,
946
- onZoomChange,
947
- className,
948
- testId = "timeline-gantt"
949
- }) {
950
- return /* @__PURE__ */ jsxRuntime.jsxs(
951
- "div",
952
- {
953
- className: ui.cn(
954
- "flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1",
955
- className
956
- ),
957
- "data-testid": `${testId}-zoom`,
958
- children: [
959
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": true }),
960
- /* @__PURE__ */ jsxRuntime.jsx(
961
- "input",
962
- {
963
- type: "range",
964
- "aria-label": "Timeline zoom",
965
- "data-testid": `${testId}-zoom-slider`,
966
- min: TIMELINE_ZOOM.MIN,
967
- max: TIMELINE_ZOOM.MAX,
968
- step: TIMELINE_ZOOM.STEP,
969
- value: zoom,
970
- onChange: (e) => onZoomChange(Number(e.target.value)),
971
- className: "h-1 w-24 cursor-pointer accent-primary"
972
- }
973
- ),
974
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": true }),
975
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "w-11 shrink-0 text-right text-[11px] tabular-nums text-muted-foreground", children: [
976
- Math.round(zoom * 100),
977
- "%"
978
- ] })
979
- ]
980
- }
981
- );
982
- }
983
- var NEUTRAL_BAR = "#94a3b8";
984
- function barBackground(colors) {
985
- const c = (colors ?? []).filter(Boolean).slice(0, 3);
986
- if (c.length === 0) return NEUTRAL_BAR;
987
- if (c.length === 1) return c[0];
988
- const step = 100 / c.length;
989
- const stops = c.map((col, i) => `${col} ${i * step}% ${(i + 1) * step}%`).join(", ");
990
- return `linear-gradient(180deg, ${stops})`;
991
- }
992
- var WEEK_MS = 7 * 24 * 60 * 60 * 1e3;
993
- function formatAxisDate(d, intervalDays) {
994
- if (intervalDays < 45) {
995
- return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
996
- }
997
- if (intervalDays < 365 * 2) {
998
- return d.toLocaleDateString("en-US", { month: "short", year: "numeric" });
999
- }
1000
- return d.toLocaleDateString("en-US", { year: "numeric" });
1001
- }
1002
- function TimelineGantt({
1003
- items,
1004
- onSelect,
1005
- selectedIds,
1006
- renderDetail,
1007
- labelWidth = 240,
1008
- onLabelWidthChange,
1009
- minLabelWidth = 120,
1010
- maxLabelWidth = 600,
1011
- zoom: zoomProp,
1012
- onZoomChange,
1013
- navigatorContainer,
1014
- navigatorTotal,
1015
- emptyMessage = "Nothing dated yet.",
1016
- className,
1017
- testId = "timeline-gantt"
1018
- }) {
1019
- const [activeIndex, setActiveIndex] = react.useState(null);
1020
- const [internalZoom, setInternalZoom] = react.useState(1);
1021
- const zoomControlled = zoomProp != null && onZoomChange != null;
1022
- const zoomValue = zoomControlled ? zoomProp : internalZoom;
1023
- const setZoomValue = zoomControlled ? onZoomChange : setInternalZoom;
1024
- const dragRef = react.useRef(null);
1025
- const chartRef = react.useRef(null);
1026
- const gutterBodyRef = react.useRef(null);
1027
- const startResize = (e) => {
1028
- if (!onLabelWidthChange) return;
1029
- e.preventDefault();
1030
- dragRef.current = { startX: e.clientX, startWidth: labelWidth };
1031
- const onMove = (ev) => {
1032
- const drag = dragRef.current;
1033
- if (!drag) return;
1034
- const next = Math.min(
1035
- maxLabelWidth,
1036
- Math.max(minLabelWidth, drag.startWidth + (ev.clientX - drag.startX))
1037
- );
1038
- onLabelWidthChange(next);
1039
- };
1040
- const onUp = () => {
1041
- dragRef.current = null;
1042
- window.removeEventListener("mousemove", onMove);
1043
- window.removeEventListener("mouseup", onUp);
1044
- };
1045
- window.addEventListener("mousemove", onMove);
1046
- window.addEventListener("mouseup", onUp);
1047
- };
1048
- const rows = items.filter((i) => parseIso2(i.start) !== null).slice().sort((a, b) => parseIso2(a.start).getTime() - parseIso2(b.start).getTime());
1049
- const select = (index) => {
1050
- setActiveIndex(index);
1051
- onSelect?.(index === null ? null : rows[index]);
1052
- };
1053
- const selectedSet = new Set(selectedIds ?? []);
1054
- const selectedRowIndex = rows.findIndex((r) => selectedSet.has(r.id));
1055
- const currentIndex = selectedRowIndex >= 0 ? selectedRowIndex : activeIndex;
1056
- const goTo = (index) => select(Math.max(0, Math.min(rows.length - 1, index)));
1057
- const navigator = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-0.5 text-sm font-light", "data-testid": `${testId}-nav`, children: [
1058
- /* @__PURE__ */ jsxRuntime.jsx(
1059
- "button",
1060
- {
1061
- type: "button",
1062
- "aria-label": "Previous event",
1063
- "data-testid": `${testId}-nav-prev`,
1064
- disabled: rows.length === 0 || currentIndex === null || currentIndex <= 0,
1065
- onClick: () => goTo((currentIndex ?? 0) - 1),
1066
- className: "rounded p-0.5 text-muted-foreground enabled:hover:bg-accent enabled:hover:text-foreground disabled:opacity-30",
1067
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
1068
- }
1069
- ),
1070
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums text-muted-foreground", "data-testid": `${testId}-nav-position`, children: [
1071
- currentIndex !== null ? currentIndex + 1 : "\u2013",
1072
- " /",
1073
- " ",
1074
- navigatorTotal ?? (rows.length > 0 ? rows.length : "\u2013")
1075
- ] }),
1076
- /* @__PURE__ */ jsxRuntime.jsx(
1077
- "button",
1078
- {
1079
- type: "button",
1080
- "aria-label": "Next event",
1081
- "data-testid": `${testId}-nav-next`,
1082
- disabled: rows.length === 0 || currentIndex !== null && currentIndex >= rows.length - 1,
1083
- onClick: () => goTo(currentIndex === null ? 0 : currentIndex + 1),
1084
- className: "rounded p-0.5 text-muted-foreground enabled:hover:bg-accent enabled:hover:text-foreground disabled:opacity-30",
1085
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
1086
- }
1087
- )
1088
- ] });
1089
- if (rows.length === 0) {
1090
- return /* @__PURE__ */ jsxRuntime.jsxs(
1091
- "div",
1092
- {
1093
- "data-testid": `${testId}-empty-state`,
1094
- className: ui.cn(
1095
- "flex flex-col items-center justify-center py-16 text-muted-foreground",
1096
- className
1097
- ),
1098
- children: [
1099
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "w-12 h-12 mb-3 opacity-30" }),
1100
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: emptyMessage }),
1101
- navigatorContainer && reactDom.createPortal(navigator, navigatorContainer)
1102
- ]
1103
- }
1104
- );
1105
- }
1106
- const allDates = rows.flatMap((i) => {
1107
- const s = parseIso2(i.start);
1108
- return [s, parseIso2(i.end ?? null) ?? s];
1109
- });
1110
- const minTime = Math.min(...allDates.map((d) => d.getTime()));
1111
- const maxTime = Math.max(...allDates.map((d) => d.getTime()));
1112
- const pad = Math.max((maxTime - minTime) * 0.04, WEEK_MS);
1113
- const axisMin = new Date(minTime - pad);
1114
- const axisMax = new Date(maxTime + pad);
1115
- const axisRange = axisMax.getTime() - axisMin.getTime();
1116
- const toPercent = (d) => Math.min(100, Math.max(0, (d.getTime() - axisMin.getTime()) / axisRange * 100));
1117
- const tickCount = Math.max(2, Math.min(50, Math.round(8 * zoomValue) + 1));
1118
- const tickStep = axisRange / (tickCount - 1);
1119
- const tickIntervalDays = tickStep / DAY_MS;
1120
- const ticks = Array.from(
1121
- { length: tickCount },
1122
- (_, i) => new Date(axisMin.getTime() + tickStep * i)
1123
- );
1124
- const today = /* @__PURE__ */ new Date();
1125
- const todayPct = toPercent(today);
1126
- const showToday = today > axisMin && today < axisMax;
1127
- const activeItem = activeIndex !== null ? rows[activeIndex] : null;
1128
- const detail = activeItem ? renderDetail?.(activeItem) : null;
1129
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex h-full min-h-0", className), children: [
1130
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex min-h-0 flex-1 flex-col p-5", children: [
1131
- /* @__PURE__ */ jsxRuntime.jsx(
1132
- "div",
1133
- {
1134
- "aria-hidden": true,
1135
- "data-testid": `${testId}-gutter-divider`,
1136
- style: { left: `calc(20px + ${labelWidth}px)` },
1137
- className: "pointer-events-none absolute top-0 bottom-0 z-30 w-[3px] -translate-x-1/2 bg-border"
1138
- }
1139
- ),
1140
- onLabelWidthChange && /* @__PURE__ */ jsxRuntime.jsx(
1141
- "div",
1142
- {
1143
- role: "separator",
1144
- "aria-orientation": "vertical",
1145
- "aria-label": "Resize event column",
1146
- "data-testid": `${testId}-label-resizer`,
1147
- onMouseDown: startResize,
1148
- style: { left: `calc(20px + ${labelWidth}px)` },
1149
- className: "absolute top-0 bottom-0 z-30 w-2 -translate-x-1/2 cursor-col-resize group",
1150
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto h-full w-[3px] transition-colors group-hover:bg-primary" })
1151
- }
1152
- ),
1153
- !zoomControlled && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 top-2 z-30 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(TimelineZoomControl, { zoom: zoomValue, onZoomChange: setZoomValue, testId }) }),
1154
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex min-h-0 flex-1", children: [
1155
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: labelWidth, flexShrink: 0 }, className: "flex min-h-0 flex-col", children: [
1156
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex h-6 shrink-0 items-center gap-1 border-b border-border pr-3 text-sm font-medium text-muted-foreground", children: [
1157
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Event" }),
1158
- navigatorContainer === void 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto", children: navigator }) : navigatorContainer && reactDom.createPortal(navigator, navigatorContainer)
1159
- ] }),
1160
- /* @__PURE__ */ jsxRuntime.jsx(
1161
- "div",
1162
- {
1163
- ref: gutterBodyRef,
1164
- "data-testid": `${testId}-gutter`,
1165
- className: "min-h-0 flex-1 overflow-hidden",
1166
- onWheel: (e) => {
1167
- if (chartRef.current) chartRef.current.scrollTop += e.deltaY;
1168
- },
1169
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-4 pb-6", children: rows.map((item, i) => {
1170
- const isActive = activeIndex === i;
1171
- const isSelected = selectedIds?.includes(item.id) ?? false;
1172
- const highlighted = isActive || isSelected;
1173
- const zebra = i % 2 === 1;
1174
- return (
1175
- // Fixed h-9 = the track row's h-7 bar + py-1, so the two
1176
- // columns stay row-for-row aligned. Clicking the label
1177
- // selects the row exactly like its bar does — the label IS
1178
- // the event's title, so it should be a target too. Keep the
1179
- // `break-words leading-snug` tail on THIS element — a scoped
1180
- // CSS rule (.facts-gantt .break-words.leading-snug) clamps it
1181
- // to one line. A selected row gets the tint plus a left
1182
- // accent bar, mirroring the facts table's edited-row mark.
1183
- /* @__PURE__ */ jsxRuntime.jsx(
1184
- "div",
1185
- {
1186
- onClick: () => select(isActive ? null : i),
1187
- className: ui.cn(
1188
- "flex h-9 cursor-pointer items-center rounded border-l-[3px] pr-3 text-xs font-medium",
1189
- isSelected ? "border-l-primary bg-primary/10" : zebra ? "border-l-transparent bg-muted" : "border-l-transparent bg-background",
1190
- highlighted ? "text-foreground" : "text-muted-foreground",
1191
- "break-words leading-snug"
1192
- ),
1193
- title: item.label,
1194
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1 truncate", children: [
1195
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mr-1 tabular-nums text-muted-foreground/60", children: [
1196
- i + 1,
1197
- "."
1198
- ] }),
1199
- item.label
1200
- ] })
1201
- },
1202
- item.id
1203
- )
1204
- );
1205
- }) })
1206
- }
1207
- )
1208
- ] }),
1209
- /* @__PURE__ */ jsxRuntime.jsx(
1210
- "div",
1211
- {
1212
- ref: chartRef,
1213
- "data-testid": `${testId}-scroller`,
1214
- onScroll: (e) => {
1215
- if (gutterBodyRef.current) gutterBodyRef.current.scrollTop = e.currentTarget.scrollTop;
1216
- },
1217
- className: ui.cn(
1218
- "scrollbar-subtle relative min-h-0 min-w-0 flex-1 overflow-y-auto",
1219
- zoomValue > 1 ? "overflow-x-auto" : "overflow-x-hidden"
1220
- ),
1221
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1222
- "div",
1223
- {
1224
- className: "relative min-h-full",
1225
- style: { width: `${zoomValue * 100}%`, minWidth: "100%" },
1226
- children: [
1227
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-20 mb-1 h-6 border-b border-border bg-background", children: ticks.map((tick, i) => {
1228
- const isFirst = i === 0;
1229
- const isLast = i === ticks.length - 1;
1230
- const edgeShift = isFirst ? "translate-x-1" : isLast ? "-translate-x-full" : "-translate-x-1/2";
1231
- return /* @__PURE__ */ jsxRuntime.jsx(
1232
- "span",
1233
- {
1234
- style: { left: `${toPercent(tick)}%` },
1235
- className: `absolute bottom-1 text-[10px] text-muted-foreground whitespace-nowrap select-none ${edgeShift}`,
1236
- children: formatAxisDate(tick, tickIntervalDays)
1237
- },
1238
- i
1239
- );
1240
- }) }),
1241
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative pt-4", children: [
1242
- ticks.map((tick, i) => /* @__PURE__ */ jsxRuntime.jsx(
1243
- "div",
1244
- {
1245
- "aria-hidden": true,
1246
- className: "pointer-events-none absolute top-0 bottom-0 z-10 border-l-2 border-border/30",
1247
- style: { left: `${toPercent(tick)}%` }
1248
- },
1249
- `grid-${i}`
1250
- )),
1251
- showToday && /* @__PURE__ */ jsxRuntime.jsxs(
1252
- "div",
1253
- {
1254
- className: "pointer-events-none absolute top-0 bottom-0 z-10",
1255
- style: { left: `${todayPct}%` },
1256
- children: [
1257
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full border-l-2 border-dashed border-muted-foreground/50" }),
1258
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-0 -translate-x-1/2 rounded border bg-background px-1 text-[9px] text-muted-foreground", children: "today" })
1259
- ]
1260
- }
1261
- ),
1262
- rows.map((item, i) => {
1263
- const startDate = parseIso2(item.start);
1264
- const endDate = parseIso2(item.end ?? null) ?? startDate;
1265
- const leftPct = toPercent(startDate);
1266
- const dayPct = DAY_MS / axisRange * 100;
1267
- const widthPct = Math.max(dayPct, toPercent(endDate) - toPercent(startDate));
1268
- const isActive = activeIndex === i;
1269
- const isSelected = selectedIds?.includes(item.id) ?? false;
1270
- const highlighted = isActive || isSelected;
1271
- const zebra = i % 2 === 1;
1272
- return (
1273
- // Fixed h-9 (h-7 bar + py-1) — the gutter's label rows use
1274
- // the same height, which is what keeps the columns aligned.
1275
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-9 py-1", children: /* @__PURE__ */ jsxRuntime.jsx(
1276
- "div",
1277
- {
1278
- className: ui.cn(
1279
- "relative h-7 overflow-visible rounded-md border border-border",
1280
- isSelected ? "bg-primary/10" : zebra ? "bg-muted" : "bg-background"
1281
- ),
1282
- children: /* @__PURE__ */ jsxRuntime.jsx(
1283
- "button",
1284
- {
1285
- "data-testid": `${testId}-bar-${i}`,
1286
- "aria-label": item.label,
1287
- "aria-pressed": highlighted,
1288
- style: {
1289
- left: `${leftPct}%`,
1290
- width: `${widthPct}%`,
1291
- // Colour-coded by the item's labels (up to three), not by
1292
- // row order — see barBackground / TimelineItem.colors.
1293
- background: barBackground(item.colors),
1294
- boxShadow: highlighted ? "0 0 0 2px white, 0 0 0 4px #6366f1" : "0 1px 3px rgba(0,0,0,.2)"
1295
- },
1296
- title: formatSpan(item.start, item.end) || void 0,
1297
- className: "absolute top-0.5 h-6 min-w-[6px] rounded cursor-pointer transition-[filter] hover:brightness-110 focus:outline-none",
1298
- onClick: () => select(isActive ? null : i)
1299
- }
1300
- )
1301
- }
1302
- ) }, item.id)
1303
- );
1304
- })
1305
- ] })
1306
- ]
1307
- }
1308
- )
1309
- }
1310
- )
1311
- ] })
1312
- ] }),
1313
- /* @__PURE__ */ jsxRuntime.jsx(
1314
- "div",
1315
- {
1316
- "data-testid": `${testId}-side-panel`,
1317
- className: ui.cn(
1318
- "border-l bg-muted/20 flex flex-col shrink-0 overflow-hidden transition-all duration-300",
1319
- activeItem ? "w-60 open" : "w-0"
1320
- ),
1321
- children: /* @__PURE__ */ jsxRuntime.jsx(
1322
- "div",
1323
- {
1324
- className: ui.cn(
1325
- "w-60 p-4 flex flex-col gap-3 transition-opacity duration-200",
1326
- activeItem ? "opacity-100" : "opacity-0"
1327
- ),
1328
- children: activeItem && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1329
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1330
- "button",
1331
- {
1332
- "data-testid": `${testId}-panel-close`,
1333
- className: "w-6 h-6 rounded flex items-center justify-center text-muted-foreground hover:bg-muted",
1334
- onClick: () => select(null),
1335
- "aria-label": "Close panel",
1336
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5" })
1337
- }
1338
- ) }),
1339
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1340
- /* @__PURE__ */ jsxRuntime.jsxs(
1341
- "div",
1342
- {
1343
- "data-testid": `${testId}-panel-title`,
1344
- className: "text-sm font-semibold text-foreground leading-snug",
1345
- children: [
1346
- activeIndex !== null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mr-1 tabular-nums text-muted-foreground", children: [
1347
- activeIndex + 1,
1348
- "."
1349
- ] }),
1350
- activeItem.label
1351
- ]
1352
- }
1353
- ),
1354
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 mt-1 text-xs text-muted-foreground", children: [
1355
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "w-3 h-3 shrink-0" }),
1356
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatSpan(activeItem.start, activeItem.end) || "Date unknown" })
1357
- ] })
1358
- ] }),
1359
- activeItem.description && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1360
- /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-border" }),
1361
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1362
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground mb-1", children: "Summary" }),
1363
- /* @__PURE__ */ jsxRuntime.jsx(
1364
- "p",
1365
- {
1366
- "data-testid": `${testId}-panel-desc`,
1367
- className: "text-xs text-muted-foreground leading-relaxed",
1368
- children: activeItem.description
1369
- }
1370
- )
1371
- ] })
1372
- ] }),
1373
- detail && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1374
- /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-border" }),
1375
- detail
1376
- ] })
1377
- ] })
1378
- }
1379
- )
1380
- }
1381
- )
1382
- ] });
1383
- }
1384
- var TOGGLE = [
1385
- { mode: "calendar", label: "Calendar", Icon: lucideReact.CalendarDays },
1386
- { mode: "gantt", label: "Gantt", Icon: lucideReact.GanttChartSquare }
1387
- ];
1388
- function Timeline({
1389
- items,
1390
- view,
1391
- defaultView = "calendar",
1392
- onSelect,
1393
- renderDetail,
1394
- emptyMessage,
1395
- className,
1396
- testId = "timeline"
1397
- }) {
1398
- const [picked, setPicked] = react.useState(defaultView);
1399
- const mode = view ?? picked;
1400
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex flex-col h-full min-h-0", className), "data-testid": testId, children: [
1401
- !view && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 p-2 border-b border-border", children: TOGGLE.map(({ mode: m, label, Icon }) => /* @__PURE__ */ jsxRuntime.jsxs(
1402
- "button",
1403
- {
1404
- type: "button",
1405
- onClick: () => setPicked(m),
1406
- "aria-pressed": mode === m,
1407
- "data-testid": `${testId}-view-${m}`,
1408
- className: ui.cn(
1409
- "flex items-center gap-1.5 rounded px-2 py-1 text-xs",
1410
- mode === m ? "bg-muted text-foreground" : "text-muted-foreground hover:text-foreground"
1411
- ),
1412
- children: [
1413
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-3.5 h-3.5" }),
1414
- label
1415
- ]
1416
- },
1417
- m
1418
- )) }),
1419
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0", children: mode === "calendar" ? /* @__PURE__ */ jsxRuntime.jsx(
1420
- TimelineCalendar,
1421
- {
1422
- items,
1423
- onSelect,
1424
- testId: `${testId}-calendar`,
1425
- emptyState: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center p-8 text-sm text-muted-foreground", children: emptyMessage ?? "Nothing dated yet." })
1426
- }
1427
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1428
- TimelineGantt,
1429
- {
1430
- items,
1431
- onSelect: (item) => item && onSelect?.(item),
1432
- renderDetail,
1433
- emptyMessage,
1434
- testId: `${testId}-gantt`
1435
- }
1436
- ) })
1437
- ] });
1438
- }
1439
514
  function SectionHeading({
1440
515
  eyebrow,
1441
516
  title,
@@ -1511,7 +586,7 @@ var ASPECT = {
1511
586
  var ROUNDED = {
1512
587
  none: "rounded-none",
1513
588
  md: "rounded-md",
1514
- lg: "rounded-xl",
589
+ lg: "rounded-lg",
1515
590
  full: "rounded-full"
1516
591
  };
1517
592
  function BlockImage({
@@ -1573,18 +648,23 @@ var TONE_SURFACE = {
1573
648
  ink: "bg-foreground text-background"
1574
649
  };
1575
650
  function renderTitle(title, emphasis) {
1576
- if (!emphasis || !title.includes(emphasis)) return title;
651
+ if (typeof title !== "string" || !emphasis || !title.includes(emphasis)) return title;
1577
652
  const parts = title.split(emphasis);
1578
653
  return parts.map((part, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1579
654
  part,
1580
655
  i < parts.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: emphasis })
1581
656
  ] }, i));
1582
657
  }
658
+ function renderLink(Link, href, children) {
659
+ return Link ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href, children }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href, children });
660
+ }
1583
661
  function Hero({
1584
662
  eyebrow,
1585
663
  title,
1586
664
  emphasis,
1587
665
  subtitle,
666
+ caption,
667
+ linkComponent: Link,
1588
668
  primaryCta,
1589
669
  secondaryCta,
1590
670
  align = "left",
@@ -1617,10 +697,14 @@ function Hero({
1617
697
  {
1618
698
  className: ui.cn("mt-8 flex flex-col gap-3 sm:flex-row", centered && "sm:justify-center"),
1619
699
  children: [
1620
- primaryCta?.label && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, size: "lg", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: primaryCta.href || "#", children: [
1621
- primaryCta.label,
1622
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-4" })
1623
- ] }) }),
700
+ primaryCta?.label && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, size: "lg", children: renderLink(
701
+ Link,
702
+ primaryCta.href || "#",
703
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
704
+ primaryCta.label,
705
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-4" })
706
+ ] })
707
+ ) }),
1624
708
  secondaryCta?.label && /* @__PURE__ */ jsxRuntime.jsx(
1625
709
  ui.Button,
1626
710
  {
@@ -1630,12 +714,13 @@ function Hero({
1630
714
  className: ui.cn(
1631
715
  onDark && "border-background/35 bg-transparent text-background hover:bg-background/10 hover:text-background"
1632
716
  ),
1633
- children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: secondaryCta.href || "#", children: secondaryCta.label })
717
+ children: renderLink(Link, secondaryCta.href || "#", secondaryCta.label)
1634
718
  }
1635
719
  )
1636
720
  ]
1637
721
  }
1638
- )
722
+ ),
723
+ caption && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cn("mt-4 text-sm", subtle), children: caption })
1639
724
  ]
1640
725
  }
1641
726
  );
@@ -1732,7 +817,7 @@ function Testimonial({ quote, author, role, avatarUrl, testId }) {
1732
817
  (author || avatarUrl) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex items-center justify-center gap-3", children: [
1733
818
  (avatarUrl || author) && /* @__PURE__ */ jsxRuntime.jsxs(ui.Avatar, { children: [
1734
819
  avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarImage, { src: avatarUrl, alt: author ?? "" }),
1735
- /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { children: initials(author || "?") })
820
+ /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { children: chunkWJMEXTVD_cjs.initials(author || "?") })
1736
821
  ] }),
1737
822
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-left", children: [
1738
823
  author && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: author }),
@@ -1766,7 +851,7 @@ function CTABanner({
1766
851
  "div",
1767
852
  {
1768
853
  className: ui.cn(
1769
- "relative isolate overflow-hidden rounded-2xl px-8 py-14 text-center",
854
+ "relative isolate overflow-hidden rounded-lg px-8 py-14 text-center",
1770
855
  onImage ? "text-white" : TONE_SURFACE2[tone] ?? TONE_SURFACE2.default
1771
856
  ),
1772
857
  style: bgStyle,
@@ -1816,35 +901,6 @@ function FAQ({ items, testId }) {
1816
901
  function RichTextBlock({ content, testId }) {
1817
902
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-3xl", "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsx(ui.AiMarkdown, { children: content ?? "" }) });
1818
903
  }
1819
- var STYLES = {
1820
- info: { wrap: "border-primary/30 bg-primary/5", icon: "text-primary", Icon: lucideReact.Info },
1821
- success: { wrap: "border-success/30 bg-success/10", icon: "text-success", Icon: lucideReact.CheckCircle2 },
1822
- warning: { wrap: "border-warning/40 bg-warning/10", icon: "text-warning", Icon: lucideReact.AlertTriangle },
1823
- danger: {
1824
- wrap: "border-destructive/30 bg-destructive/10",
1825
- icon: "text-destructive",
1826
- Icon: lucideReact.XCircle
1827
- }
1828
- };
1829
- function Callout({ variant = "info", title, body, testId }) {
1830
- const style = STYLES[variant] ?? STYLES.info;
1831
- const Icon = style.Icon;
1832
- return /* @__PURE__ */ jsxRuntime.jsxs(
1833
- "div",
1834
- {
1835
- className: ui.cn("flex gap-3 rounded-lg border p-4 text-foreground", style.wrap),
1836
- "data-testid": testId,
1837
- role: "note",
1838
- children: [
1839
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: ui.cn("mt-0.5 size-5 shrink-0", style.icon), "aria-hidden": true }),
1840
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
1841
- title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold", children: title }),
1842
- body && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: body })
1843
- ] })
1844
- ]
1845
- }
1846
- );
1847
- }
1848
904
  var SIZE = {
1849
905
  sm: "size-8 text-xs",
1850
906
  md: "size-10 text-sm",
@@ -1854,39 +910,90 @@ var SIZE = {
1854
910
  function AvatarBlock({ src, name = "", size = "md", testId }) {
1855
911
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Avatar, { className: ui.cn(SIZE[size] ?? SIZE.md), "data-testid": testId, children: [
1856
912
  src && /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarImage, { src, alt: name }),
1857
- /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { className: "font-semibold", children: initials(name || "?") })
913
+ /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { className: "font-semibold", children: chunkWJMEXTVD_cjs.initials(name || "?") })
1858
914
  ] });
1859
915
  }
1860
- function Navbar({ brand, links, cta, testId }) {
1861
- return /* @__PURE__ */ jsxRuntime.jsx("header", { className: "border-b border-border bg-background", "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "mx-auto flex max-w-7xl items-center justify-between gap-6 px-5 py-4 lg:px-8", children: [
1862
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold tracking-tight", children: brand }),
1863
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden items-center gap-6 md:flex", children: (links ?? []).map((link, i) => /* @__PURE__ */ jsxRuntime.jsx(
1864
- "a",
916
+ var DEFAULT_LABELS = { openMenu: "Open menu", closeMenu: "Close menu" };
917
+ function Navbar({
918
+ brand,
919
+ brandHref,
920
+ links,
921
+ cta,
922
+ ctaSlot,
923
+ linkComponent: Link,
924
+ mobileMenu,
925
+ labels,
926
+ testId,
927
+ testIds
928
+ }) {
929
+ const [isOpen, setIsOpen] = react.useState(false);
930
+ const l = { ...DEFAULT_LABELS, ...labels };
931
+ const items = links ?? [];
932
+ const linkId = (i) => testIds?.link?.(i) ?? (testId ? `${testId}-link-${i}` : void 0);
933
+ const ctaId = testIds?.cta ?? (testId ? `${testId}-cta` : void 0);
934
+ const menuId = testIds?.menu ?? (testId ? `${testId}-menu` : void 0);
935
+ const menuButtonId = testIds?.menuButton ?? (testId ? `${testId}-menu-button` : void 0);
936
+ const anchor = (href, className, children, id) => Link ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href, className, "data-testid": id, children }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href, className, "data-testid": id, children });
937
+ const linkClass = "text-sm font-medium text-muted-foreground transition-colors hover:text-foreground";
938
+ const brandNode = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-semibold tracking-tight", children: brand });
939
+ const ctaNode = ctaSlot ?? (cta?.label && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, size: "sm", children: anchor(cta.href || "#", void 0, cta.label, ctaId) }));
940
+ return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "border-b border-border bg-background", "data-testid": testId, children: [
941
+ /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "mx-auto flex max-w-7xl items-center justify-between gap-6 px-5 py-4 lg:px-8", children: [
942
+ brandHref ? anchor(brandHref, void 0, brandNode) : brandNode,
943
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden items-center gap-6 md:flex", children: items.map((link, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: anchor(link.href || "#", linkClass, link.label, linkId(i)) }, i)) }),
944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
945
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block", children: ctaNode }),
946
+ /* @__PURE__ */ jsxRuntime.jsx(
947
+ "button",
948
+ {
949
+ type: "button",
950
+ className: "rounded-md p-2 text-foreground hover:bg-muted md:hidden",
951
+ "aria-expanded": isOpen,
952
+ "aria-label": isOpen ? l.closeMenu : l.openMenu,
953
+ onClick: () => setIsOpen((open) => !open),
954
+ "data-testid": menuButtonId,
955
+ children: isOpen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "size-5" })
956
+ }
957
+ )
958
+ ] })
959
+ ] }),
960
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
961
+ "div",
1865
962
  {
1866
- href: link.href || "#",
1867
- className: "text-sm font-medium text-muted-foreground transition-colors hover:text-foreground",
1868
- "data-testid": testId && `${testId}-link-${i}`,
1869
- children: link.label
1870
- },
1871
- i
1872
- )) }),
1873
- cta?.label && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: cta.href || "#", children: cta.label }) })
1874
- ] }) });
963
+ className: "border-t border-border px-5 py-4 md:hidden",
964
+ "data-slot": "navbar-mobile-menu",
965
+ "data-testid": menuId,
966
+ children: mobileMenu ?? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
967
+ items.map((link, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: anchor(link.href || "#", linkClass, link.label) }, i)),
968
+ ctaNode
969
+ ] })
970
+ }
971
+ )
972
+ ] });
1875
973
  }
1876
- function Footer({ columns, copyright, testId }) {
974
+ function Footer({
975
+ columns,
976
+ copyright,
977
+ brand,
978
+ blurb,
979
+ legal,
980
+ linkComponent: Link,
981
+ testId
982
+ }) {
983
+ const linkClass = "text-sm text-muted-foreground transition-colors hover:text-foreground";
1877
984
  return /* @__PURE__ */ jsxRuntime.jsx("footer", { className: "border-t border-border bg-muted text-foreground", "data-testid": testId, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-7xl px-5 py-14 lg:px-8", children: [
985
+ (brand || blurb) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-10 max-w-md", "data-slot": "footer-brand", children: [
986
+ brand && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-lg font-semibold tracking-tight", children: brand }),
987
+ blurb && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: blurb })
988
+ ] }),
1878
989
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-8 sm:grid-cols-2 lg:grid-cols-4", children: (columns ?? []).map((col, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": testId && `${testId}-col-${i}`, children: [
1879
990
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold tracking-tight", children: col.heading }),
1880
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-4 space-y-2", children: (col.links ?? []).map((link, j) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1881
- "a",
1882
- {
1883
- href: link.href || "#",
1884
- className: "text-sm text-muted-foreground transition-colors hover:text-foreground",
1885
- children: link.label
1886
- }
1887
- ) }, j)) })
991
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-4 space-y-2", children: (col.links ?? []).map((link, j) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: Link ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href: link.href || "#", className: linkClass, children: link.label }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href: link.href || "#", className: linkClass, children: link.label }) }, j)) })
1888
992
  ] }, i)) }),
1889
- copyright && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-12 border-t border-border pt-6 text-sm text-muted-foreground", children: copyright })
993
+ (copyright || legal) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-12 flex flex-col gap-3 border-t border-border pt-6 text-sm text-muted-foreground sm:flex-row sm:items-center sm:justify-between", children: [
994
+ copyright && /* @__PURE__ */ jsxRuntime.jsx("p", { children: copyright }),
995
+ legal && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "footer-legal", children: legal })
996
+ ] })
1890
997
  ] }) });
1891
998
  }
1892
999
  function ListBlock({ ordered = false, items, testId }) {
@@ -1988,38 +1095,33 @@ function PricingTable({ plans, testId }) {
1988
1095
  );
1989
1096
  }
1990
1097
  function Tabs({ items, testId }) {
1991
- const [active, setActive] = react.useState(0);
1992
1098
  const list = items ?? [];
1993
- const current = list[Math.min(active, Math.max(list.length - 1, 0))];
1994
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": testId, children: [
1995
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 border-b border-border", role: "tablist", children: list.map((t, i) => {
1996
- const selected = i === active;
1997
- return /* @__PURE__ */ jsxRuntime.jsx(
1998
- "button",
1999
- {
2000
- type: "button",
2001
- role: "tab",
2002
- "aria-selected": selected,
2003
- onClick: () => setActive(i),
2004
- className: ui.cn(
2005
- "-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors",
2006
- selected ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
2007
- ),
2008
- "data-testid": testId && `${testId}-tab-${i}`,
2009
- children: t.label
2010
- },
2011
- i
2012
- );
2013
- }) }),
2014
- current && /* @__PURE__ */ jsxRuntime.jsx(
2015
- "div",
1099
+ const [active, setActive] = react.useState("0");
1100
+ const activeIndex = Math.min(Number(active), Math.max(list.length - 1, 0));
1101
+ return /* @__PURE__ */ jsxRuntime.jsxs(TabsPrimitive__namespace.Root, { value: String(activeIndex), onValueChange: setActive, "data-testid": testId, children: [
1102
+ /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.List, { className: "flex flex-wrap gap-1 border-b border-border", children: list.map((t, i) => /* @__PURE__ */ jsxRuntime.jsx(
1103
+ TabsPrimitive__namespace.Trigger,
2016
1104
  {
2017
- role: "tabpanel",
2018
- className: "pt-5 text-sm leading-relaxed text-muted-foreground",
2019
- "data-testid": testId && `${testId}-panel`,
2020
- children: current.content
2021
- }
2022
- )
1105
+ value: String(i),
1106
+ className: ui.cn(
1107
+ "-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
1108
+ i === activeIndex ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
1109
+ ),
1110
+ "data-testid": testId && `${testId}-tab-${i}`,
1111
+ children: t.label
1112
+ },
1113
+ i
1114
+ )) }),
1115
+ list.map((t, i) => /* @__PURE__ */ jsxRuntime.jsx(
1116
+ TabsPrimitive__namespace.Content,
1117
+ {
1118
+ value: String(i),
1119
+ className: "pt-5 text-sm leading-relaxed text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1120
+ "data-testid": i === activeIndex ? testId && `${testId}-panel` : void 0,
1121
+ children: t.content
1122
+ },
1123
+ i
1124
+ ))
2023
1125
  ] });
2024
1126
  }
2025
1127
  function Accordion({ items, allowMultiple = false, testId }) {
@@ -2126,29 +1228,77 @@ function VideoEmbed({
2126
1228
  }
2127
1229
  ) : url ? /* @__PURE__ */ jsxRuntime.jsx("video", { src: url, controls: true, className: "size-full", "data-testid": testId && `${testId}-video` }) : null });
2128
1230
  }
1231
+ function initialValues(fields) {
1232
+ const values = {};
1233
+ for (const f of fields) values[f.name] = f.defaultValue ?? "";
1234
+ return values;
1235
+ }
1236
+ var INPUT_CLASS = "w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:border-primary";
2129
1237
  function ContactForm({
2130
1238
  fields,
2131
1239
  submitLabel = "Send",
2132
1240
  action,
1241
+ onSubmit,
2133
1242
  successMessage = "Thanks \u2014 we\u2019ll be in touch shortly.",
2134
- testId
1243
+ renderSuccess,
1244
+ resetLabel,
1245
+ onValuesChange,
1246
+ footerSlot,
1247
+ testId,
1248
+ testIds
2135
1249
  }) {
2136
- const [sent, setSent] = react.useState(false);
1250
+ const [sentValues, setSentValues] = react.useState(null);
1251
+ const [isSending, setIsSending] = react.useState(false);
2137
1252
  const list = fields ?? [];
2138
- const onSubmit = (e) => {
2139
- if (!action) {
2140
- e.preventDefault();
2141
- setSent(true);
1253
+ const [liveValues, setLiveValues] = react.useState(() => initialValues(list));
1254
+ const ids = {
1255
+ form: testIds?.form ?? testId,
1256
+ success: testIds?.success ?? (testId ? `${testId}-success` : void 0),
1257
+ submit: testIds?.submit ?? (testId ? `${testId}-submit` : void 0),
1258
+ field: (name) => testIds?.field?.(name) ?? (testId ? `${testId}-field-${name}` : void 0)
1259
+ };
1260
+ const reset = () => {
1261
+ setLiveValues(initialValues(list));
1262
+ setSentValues(null);
1263
+ };
1264
+ const handleChange = (e) => {
1265
+ const values = { ...initialValues(list) };
1266
+ new FormData(e.currentTarget).forEach((v, k) => {
1267
+ if (typeof v === "string") values[k] = v;
1268
+ });
1269
+ setLiveValues(values);
1270
+ onValuesChange?.(values);
1271
+ };
1272
+ const handleSubmit = async (e) => {
1273
+ if (action && !onSubmit) return;
1274
+ e.preventDefault();
1275
+ const values = {};
1276
+ new FormData(e.currentTarget).forEach((v, k) => {
1277
+ if (typeof v === "string") values[k] = v;
1278
+ });
1279
+ if (onSubmit) {
1280
+ setIsSending(true);
1281
+ try {
1282
+ await onSubmit(values);
1283
+ } catch {
1284
+ return;
1285
+ } finally {
1286
+ setIsSending(false);
1287
+ }
2142
1288
  }
1289
+ setSentValues(values);
2143
1290
  };
2144
- if (sent) {
2145
- return /* @__PURE__ */ jsxRuntime.jsx(
2146
- "p",
1291
+ if (sentValues) {
1292
+ return renderSuccess ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": ids.success, children: renderSuccess(sentValues, reset) }) : /* @__PURE__ */ jsxRuntime.jsxs(
1293
+ "div",
2147
1294
  {
2148
1295
  className: "rounded-lg border border-border bg-muted p-6 text-center text-sm text-foreground",
2149
1296
  role: "status",
2150
- "data-testid": testId && `${testId}-success`,
2151
- children: successMessage
1297
+ "data-testid": ids.success,
1298
+ children: [
1299
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: successMessage }),
1300
+ resetLabel && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "outline", className: "mt-4", onClick: reset, children: resetLabel })
1301
+ ]
2152
1302
  }
2153
1303
  );
2154
1304
  }
@@ -2156,42 +1306,59 @@ function ContactForm({
2156
1306
  "form",
2157
1307
  {
2158
1308
  action,
2159
- method: action ? "post" : void 0,
2160
- onSubmit,
1309
+ method: action && !onSubmit ? "post" : void 0,
1310
+ onSubmit: handleSubmit,
1311
+ onChange: handleChange,
2161
1312
  className: "mx-auto flex max-w-xl flex-col gap-4",
2162
- "data-testid": testId,
1313
+ "data-testid": ids.form,
2163
1314
  children: [
2164
- list.map((f, i) => {
2165
- const inputClass = "w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:border-primary";
2166
- return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1.5 text-left", children: [
2167
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: f.label }),
2168
- f.type === "textarea" ? /* @__PURE__ */ jsxRuntime.jsx(
2169
- "textarea",
2170
- {
2171
- name: f.name,
2172
- required: f.required,
2173
- rows: 4,
2174
- className: inputClass,
2175
- "data-testid": testId && `${testId}-field-${f.name}`
2176
- }
2177
- ) : /* @__PURE__ */ jsxRuntime.jsx(
2178
- "input",
2179
- {
2180
- name: f.name,
2181
- type: f.type || "text",
2182
- required: f.required,
2183
- className: inputClass,
2184
- "data-testid": testId && `${testId}-field-${f.name}`
2185
- }
2186
- )
2187
- ] }, i);
2188
- }),
1315
+ list.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex flex-col gap-1.5 text-left", children: [
1316
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: f.label }),
1317
+ f.type === "textarea" ? /* @__PURE__ */ jsxRuntime.jsx(
1318
+ "textarea",
1319
+ {
1320
+ name: f.name,
1321
+ required: f.required,
1322
+ rows: 4,
1323
+ defaultValue: f.defaultValue,
1324
+ placeholder: f.placeholder,
1325
+ className: INPUT_CLASS,
1326
+ "data-testid": ids.field(f.name)
1327
+ }
1328
+ ) : f.type === "select" ? /* @__PURE__ */ jsxRuntime.jsxs(
1329
+ "select",
1330
+ {
1331
+ name: f.name,
1332
+ required: f.required,
1333
+ defaultValue: f.defaultValue ?? "",
1334
+ className: INPUT_CLASS,
1335
+ "data-testid": ids.field(f.name),
1336
+ children: [
1337
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: f.required, children: f.placeholder ?? "" }),
1338
+ (f.options ?? []).map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
1339
+ ]
1340
+ }
1341
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1342
+ "input",
1343
+ {
1344
+ name: f.name,
1345
+ type: f.type || "text",
1346
+ required: f.required,
1347
+ defaultValue: f.defaultValue,
1348
+ placeholder: f.placeholder,
1349
+ className: INPUT_CLASS,
1350
+ "data-testid": ids.field(f.name)
1351
+ }
1352
+ )
1353
+ ] }, i)),
1354
+ typeof footerSlot === "function" ? footerSlot(liveValues) : footerSlot,
2189
1355
  /* @__PURE__ */ jsxRuntime.jsx(
2190
1356
  ui.Button,
2191
1357
  {
2192
1358
  type: "submit",
2193
1359
  className: ui.cn("mt-1 self-start"),
2194
- "data-testid": testId && `${testId}-submit`,
1360
+ disabled: isSending,
1361
+ "data-testid": ids.submit,
2195
1362
  children: submitLabel
2196
1363
  }
2197
1364
  )
@@ -2255,41 +1422,175 @@ function MediaText({
2255
1422
  copy
2256
1423
  ] }) });
2257
1424
  }
1425
+ var TONES = {
1426
+ default: {
1427
+ text: "text-foreground",
1428
+ muted: "text-muted-foreground",
1429
+ subtle: "text-muted-foreground",
1430
+ accent: "text-primary",
1431
+ hairline: "border-border",
1432
+ panel: "border-border bg-card text-card-foreground",
1433
+ panelHover: "hover:border-primary/45 hover:bg-muted/60",
1434
+ chip: "border-border text-muted-foreground",
1435
+ tile: "border-primary/30 text-primary"
1436
+ },
1437
+ inverse: {
1438
+ text: "text-background",
1439
+ muted: "text-background/70",
1440
+ subtle: "text-background/55",
1441
+ accent: "text-primary",
1442
+ hairline: "border-background/15",
1443
+ panel: "border-background/15 bg-background/5 text-background",
1444
+ panelHover: "hover:border-primary/45 hover:bg-background/10",
1445
+ chip: "border-background/20 text-background/65",
1446
+ tile: "border-primary/40 text-primary"
1447
+ }
1448
+ };
1449
+ var EditorialToneContext = react.createContext("default");
1450
+ function useEditorialTone(override) {
1451
+ const inherited = react.useContext(EditorialToneContext);
1452
+ const tone = override ?? inherited;
1453
+ return { tone, ...TONES[tone] };
1454
+ }
1455
+ function formatIndex(index) {
1456
+ return typeof index === "number" ? String(index).padStart(2, "0") : index;
1457
+ }
1458
+ var CLAMP = { 2: "line-clamp-2", 3: "line-clamp-3", 4: "line-clamp-4" };
1459
+ function ProfileCard({
1460
+ name,
1461
+ role,
1462
+ kicker,
1463
+ bio,
1464
+ avatarUrl,
1465
+ avatar,
1466
+ avatarClassName,
1467
+ meta,
1468
+ href,
1469
+ linkComponent,
1470
+ bioLines = 3,
1471
+ headingLevel = 3,
1472
+ className,
1473
+ testId
1474
+ }) {
1475
+ const t = useEditorialTone();
1476
+ const Heading = `h${headingLevel}`;
1477
+ return /* @__PURE__ */ jsxRuntime.jsx(BlockLink, { href, linkComponent, className: "group block h-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
1478
+ "article",
1479
+ {
1480
+ className: ui.cn(
1481
+ "flex h-full flex-col rounded-sm border p-6 transition-colors duration-300",
1482
+ t.panel,
1483
+ href && t.panelHover,
1484
+ className
1485
+ ),
1486
+ "data-slot": "profile-card",
1487
+ "data-testid": testId,
1488
+ children: [
1489
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
1490
+ avatar ?? /* @__PURE__ */ jsxRuntime.jsxs(ui.Avatar, { className: "size-14 text-sm", children: [
1491
+ avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarImage, { src: avatarUrl, alt: "" }),
1492
+ /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { className: avatarClassName, children: chunkWJMEXTVD_cjs.initials(name || "?") })
1493
+ ] }),
1494
+ href && /* @__PURE__ */ jsxRuntime.jsx(
1495
+ lucideReact.ArrowUpRight,
1496
+ {
1497
+ "aria-hidden": "true",
1498
+ className: ui.cn("size-4 shrink-0 transition-colors group-hover:text-primary", t.subtle)
1499
+ }
1500
+ )
1501
+ ] }),
1502
+ /* @__PURE__ */ jsxRuntime.jsx(Heading, { className: ui.cn("mt-5 font-display text-lg font-semibold", t.text), children: name }),
1503
+ role && /* @__PURE__ */ jsxRuntime.jsx("p", { className: ui.cn("text-sm", t.muted), children: role }),
1504
+ kicker && /* @__PURE__ */ jsxRuntime.jsx("p", { className: ui.cn("mt-0.5 text-xs", t.accent), children: kicker }),
1505
+ bio && /* @__PURE__ */ jsxRuntime.jsx(
1506
+ "p",
1507
+ {
1508
+ className: ui.cn(
1509
+ "mt-4 text-sm leading-relaxed",
1510
+ t.muted,
1511
+ bioLines ? CLAMP[bioLines] : void 0
1512
+ ),
1513
+ children: bio
1514
+ }
1515
+ ),
1516
+ meta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto pt-5", children: meta })
1517
+ ]
1518
+ }
1519
+ ) });
1520
+ }
2258
1521
  var COLS3 = {
2259
1522
  "2": "sm:grid-cols-2",
2260
1523
  "3": "sm:grid-cols-2 lg:grid-cols-3",
2261
1524
  "4": "sm:grid-cols-2 lg:grid-cols-4"
2262
1525
  };
2263
- function TeamGrid({ members, columns = "3", linkComponent, testId }) {
2264
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cn("grid gap-6", COLS3[columns] ?? COLS3["3"]), "data-testid": testId, children: (members ?? []).map((m, i) => /* @__PURE__ */ jsxRuntime.jsx(
2265
- BlockLink,
1526
+ function TeamGrid({
1527
+ members,
1528
+ columns = "3",
1529
+ variant = "centered",
1530
+ renderMeta,
1531
+ linkComponent,
1532
+ testId
1533
+ }) {
1534
+ const profile = variant === "profile";
1535
+ return /* @__PURE__ */ jsxRuntime.jsx(
1536
+ "div",
2266
1537
  {
2267
- href: m.href,
2268
- linkComponent,
2269
- className: ui.cn("block h-full", m.href && "group"),
2270
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2271
- ui.Card,
2272
- {
2273
- variant: "outline",
2274
- className: ui.cn(
2275
- "flex h-full flex-col items-center p-6 text-center",
2276
- m.href && "transition-colors group-hover:border-primary/40"
2277
- ),
2278
- "data-testid": testId && `${testId}-item-${i}`,
2279
- children: [
2280
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Avatar, { className: "size-20", children: [
2281
- m.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarImage, { src: m.avatarUrl, alt: m.name }),
2282
- /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { children: initials(m.name || "?") })
2283
- ] }),
2284
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-4 text-base font-semibold tracking-tight", children: m.name }),
2285
- m.role && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-primary", children: m.role }),
2286
- m.bio && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: m.bio })
2287
- ]
1538
+ className: ui.cn("grid", profile ? "gap-4" : "gap-6", COLS3[columns] ?? COLS3["3"]),
1539
+ "data-testid": testId,
1540
+ children: (members ?? []).map((m, i) => {
1541
+ const cardTestId = m.testId ?? (testId ? `${testId}-item-${i}` : void 0);
1542
+ const meta = renderMeta?.(m, i);
1543
+ if (profile) {
1544
+ return /* @__PURE__ */ jsxRuntime.jsx(
1545
+ ProfileCard,
1546
+ {
1547
+ name: m.name,
1548
+ role: m.role,
1549
+ kicker: m.kicker,
1550
+ bio: m.bio,
1551
+ avatarUrl: m.avatarUrl,
1552
+ href: m.href,
1553
+ linkComponent,
1554
+ meta,
1555
+ testId: cardTestId
1556
+ },
1557
+ i
1558
+ );
2288
1559
  }
2289
- )
2290
- },
2291
- i
2292
- )) });
1560
+ return /* @__PURE__ */ jsxRuntime.jsx(
1561
+ BlockLink,
1562
+ {
1563
+ href: m.href,
1564
+ linkComponent,
1565
+ className: ui.cn("block h-full", m.href && "group"),
1566
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1567
+ ui.Card,
1568
+ {
1569
+ variant: "outline",
1570
+ className: ui.cn(
1571
+ "flex h-full flex-col items-center p-6 text-center",
1572
+ m.href && "transition-colors group-hover:border-primary/40"
1573
+ ),
1574
+ "data-testid": cardTestId,
1575
+ children: [
1576
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Avatar, { className: "size-20", children: [
1577
+ m.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarImage, { src: m.avatarUrl, alt: m.name }),
1578
+ /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { children: chunkWJMEXTVD_cjs.initials(m.name || "?") })
1579
+ ] }),
1580
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-4 text-base font-semibold tracking-tight", children: m.name }),
1581
+ m.role && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-primary", children: m.role }),
1582
+ m.kicker && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: m.kicker }),
1583
+ m.bio && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: m.bio }),
1584
+ meta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: meta })
1585
+ ]
1586
+ }
1587
+ )
1588
+ },
1589
+ i
1590
+ );
1591
+ })
1592
+ }
1593
+ );
2293
1594
  }
2294
1595
  function Steps({ steps, variant = "numbered", testId }) {
2295
1596
  const list = steps ?? [];
@@ -2330,7 +1631,7 @@ function TestimonialGrid({ items, columns = "3", testId }) {
2330
1631
  (t.author || t.avatarUrl) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-5 flex items-center gap-3", children: [
2331
1632
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Avatar, { className: "size-9", children: [
2332
1633
  t.avatarUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarImage, { src: t.avatarUrl, alt: t.author ?? "" }),
2333
- /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { children: initials(t.author || "?") })
1634
+ /* @__PURE__ */ jsxRuntime.jsx(ui.AvatarFallback, { children: chunkWJMEXTVD_cjs.initials(t.author || "?") })
2334
1635
  ] }),
2335
1636
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2336
1637
  t.author && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: t.author }),
@@ -2351,10 +1652,10 @@ exports.Banner = Banner;
2351
1652
  exports.BlockImage = BlockImage;
2352
1653
  exports.BlockLink = BlockLink;
2353
1654
  exports.CTABanner = CTABanner;
2354
- exports.Callout = Callout;
2355
1655
  exports.Columns = Columns;
2356
1656
  exports.ContactForm = ContactForm;
2357
1657
  exports.Container = Container;
1658
+ exports.EditorialToneContext = EditorialToneContext;
2358
1659
  exports.FAQ = FAQ;
2359
1660
  exports.FONT_PAIRINGS = FONT_PAIRINGS;
2360
1661
  exports.FeatureGrid = FeatureGrid;
@@ -2366,21 +1667,17 @@ exports.LogoCloud = LogoCloud;
2366
1667
  exports.MediaText = MediaText;
2367
1668
  exports.Navbar = Navbar;
2368
1669
  exports.PricingTable = PricingTable;
1670
+ exports.ProfileCard = ProfileCard;
2369
1671
  exports.RichTextBlock = RichTextBlock;
2370
1672
  exports.SectionHeading = SectionHeading;
2371
1673
  exports.Spacer = Spacer;
2372
1674
  exports.Steps = Steps;
2373
1675
  exports.THEME_STYLE_ID = THEME_STYLE_ID;
2374
- exports.TIMELINE_ZOOM = TIMELINE_ZOOM;
2375
1676
  exports.Tabs = Tabs;
2376
1677
  exports.TeamGrid = TeamGrid;
2377
1678
  exports.Testimonial = Testimonial;
2378
1679
  exports.TestimonialGrid = TestimonialGrid;
2379
1680
  exports.ThemeEditor = ThemeEditor;
2380
- exports.Timeline = Timeline;
2381
- exports.TimelineCalendar = TimelineCalendar;
2382
- exports.TimelineGantt = TimelineGantt;
2383
- exports.TimelineZoomControl = TimelineZoomControl;
2384
1681
  exports.VideoEmbed = VideoEmbed;
2385
1682
  exports.applyFontVars = applyFontVars;
2386
1683
  exports.applyStoredTheme = applyStoredTheme;
@@ -2390,28 +1687,16 @@ exports.assetRefId = assetRefId;
2390
1687
  exports.clearFontVars = clearFontVars;
2391
1688
  exports.clearThemeVars = clearThemeVars;
2392
1689
  exports.createThemeStore = createThemeStore;
2393
- exports.dayKey = dayKey;
2394
- exports.daysUntil = daysUntil;
2395
- exports.fmtDate = fmtDate;
2396
- exports.fmtDateTime = fmtDateTime;
2397
1690
  exports.fontPackages = fontPackages;
2398
- exports.formatPageRefs = formatPageRefs;
2399
- exports.formatSpan = formatSpan;
2400
- exports.fromNow = fromNow;
2401
- exports.gbp = gbp;
1691
+ exports.formatIndex = formatIndex;
2402
1692
  exports.getFontPairing = getFontPairing;
2403
- exports.hrs = hrs;
2404
- exports.initials = initials;
2405
1693
  exports.isAssetRef = isAssetRef;
2406
1694
  exports.matchFontPairing = matchFontPairing;
2407
- exports.monthLabel = monthLabel;
2408
- exports.parseIso = parseIso2;
2409
- exports.pct = pct;
2410
1695
  exports.tid = tid;
2411
1696
  exports.toEmbedUrl = toEmbedUrl;
2412
1697
  exports.toHslTriplet = toHslTriplet;
2413
1698
  exports.useAssetRenderer = useAssetRenderer;
2414
1699
  exports.useAssetResolverActive = useAssetResolverActive;
2415
- exports.utcDay = utcDay;
2416
- //# sourceMappingURL=chunk-DBAUZD7A.cjs.map
2417
- //# sourceMappingURL=chunk-DBAUZD7A.cjs.map
1700
+ exports.useEditorialTone = useEditorialTone;
1701
+ //# sourceMappingURL=chunk-DREI7EQ2.cjs.map
1702
+ //# sourceMappingURL=chunk-DREI7EQ2.cjs.map