@tollerud/ui 1.1.5 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/AGENTS.md +36 -13
  2. package/CHANGELOG.md +411 -0
  3. package/COMPONENTS.md +951 -0
  4. package/GETTING_STARTED.md +159 -0
  5. package/README.md +51 -43
  6. package/SKILL.md +59 -24
  7. package/components.json +18 -0
  8. package/dist/accordion.d.ts +20 -0
  9. package/dist/accordion.js +5 -0
  10. package/dist/accordion.js.map +1 -0
  11. package/dist/action-diff.d.ts +26 -0
  12. package/dist/action-diff.js +5 -0
  13. package/dist/action-diff.js.map +1 -0
  14. package/dist/action-row.d.ts +36 -0
  15. package/dist/action-row.js +6 -0
  16. package/dist/action-row.js.map +1 -0
  17. package/dist/alert-inbox.d.ts +23 -0
  18. package/dist/alert-inbox.js +6 -0
  19. package/dist/alert-inbox.js.map +1 -0
  20. package/dist/alert.d.ts +33 -0
  21. package/dist/alert.js +5 -0
  22. package/dist/alert.js.map +1 -0
  23. package/dist/approval-card.d.ts +27 -0
  24. package/dist/approval-card.js +5 -0
  25. package/dist/approval-card.js.map +1 -0
  26. package/dist/area-chart.d.ts +10 -0
  27. package/dist/area-chart.js +5 -0
  28. package/dist/area-chart.js.map +1 -0
  29. package/dist/avatar.d.ts +28 -0
  30. package/dist/avatar.js +5 -0
  31. package/dist/avatar.js.map +1 -0
  32. package/dist/backup-status-panel.d.ts +25 -0
  33. package/dist/backup-status-panel.js +6 -0
  34. package/dist/backup-status-panel.js.map +1 -0
  35. package/dist/badge.d.ts +17 -0
  36. package/dist/badge.js +5 -0
  37. package/dist/badge.js.map +1 -0
  38. package/dist/bar-chart.d.ts +15 -0
  39. package/dist/bar-chart.js +5 -0
  40. package/dist/bar-chart.js.map +1 -0
  41. package/dist/bento-dashboard.d.ts +30 -0
  42. package/dist/bento-dashboard.js +10 -0
  43. package/dist/bento-dashboard.js.map +1 -0
  44. package/dist/breadcrumb.d.ts +16 -0
  45. package/dist/breadcrumb.js +5 -0
  46. package/dist/breadcrumb.js.map +1 -0
  47. package/dist/button.d.ts +29 -0
  48. package/dist/button.js +5 -0
  49. package/dist/button.js.map +1 -0
  50. package/dist/card.d.ts +10 -0
  51. package/dist/card.js +5 -0
  52. package/dist/card.js.map +1 -0
  53. package/dist/checkbox.d.ts +9 -0
  54. package/dist/checkbox.js +5 -0
  55. package/dist/checkbox.js.map +1 -0
  56. package/dist/chunk-2QWKOCWF.js +79 -0
  57. package/dist/chunk-2QWKOCWF.js.map +1 -0
  58. package/dist/chunk-3LTW224O.js +53 -0
  59. package/dist/chunk-3LTW224O.js.map +1 -0
  60. package/dist/chunk-3XTZPDNV.js +94 -0
  61. package/dist/chunk-3XTZPDNV.js.map +1 -0
  62. package/dist/chunk-435JHF7G.js +65 -0
  63. package/dist/chunk-435JHF7G.js.map +1 -0
  64. package/dist/chunk-4PA2ACNF.js +52 -0
  65. package/dist/chunk-4PA2ACNF.js.map +1 -0
  66. package/dist/chunk-5GWHUJ5D.js +29 -0
  67. package/dist/chunk-5GWHUJ5D.js.map +1 -0
  68. package/dist/chunk-6FUKJD3W.js +123 -0
  69. package/dist/chunk-6FUKJD3W.js.map +1 -0
  70. package/dist/chunk-6IS2AYYG.js +106 -0
  71. package/dist/chunk-6IS2AYYG.js.map +1 -0
  72. package/dist/chunk-6PZKU6ZL.js +78 -0
  73. package/dist/chunk-6PZKU6ZL.js.map +1 -0
  74. package/dist/chunk-6SKTH45H.js +75 -0
  75. package/dist/chunk-6SKTH45H.js.map +1 -0
  76. package/dist/chunk-6UXW5YUC.js +77 -0
  77. package/dist/chunk-6UXW5YUC.js.map +1 -0
  78. package/dist/chunk-7EP2T3OW.js +52 -0
  79. package/dist/chunk-7EP2T3OW.js.map +1 -0
  80. package/dist/chunk-7J5QXUQN.js +38 -0
  81. package/dist/chunk-7J5QXUQN.js.map +1 -0
  82. package/dist/chunk-A6L5C3IJ.js +47 -0
  83. package/dist/chunk-A6L5C3IJ.js.map +1 -0
  84. package/dist/chunk-ADE22JSR.js +54 -0
  85. package/dist/chunk-ADE22JSR.js.map +1 -0
  86. package/dist/chunk-ANW6J6PV.js +42 -0
  87. package/dist/chunk-ANW6J6PV.js.map +1 -0
  88. package/dist/chunk-APFFKNPS.js +80 -0
  89. package/dist/chunk-APFFKNPS.js.map +1 -0
  90. package/dist/chunk-AQT3FZRQ.js +23 -0
  91. package/dist/chunk-AQT3FZRQ.js.map +1 -0
  92. package/dist/chunk-AZADSX4Z.js +85 -0
  93. package/dist/chunk-AZADSX4Z.js.map +1 -0
  94. package/dist/chunk-BPCH5LJ3.js +36 -0
  95. package/dist/chunk-BPCH5LJ3.js.map +1 -0
  96. package/dist/chunk-CDI7353B.js +40 -0
  97. package/dist/chunk-CDI7353B.js.map +1 -0
  98. package/dist/chunk-CKNWXYMA.js +53 -0
  99. package/dist/chunk-CKNWXYMA.js.map +1 -0
  100. package/dist/chunk-DNJI65VQ.js +22 -0
  101. package/dist/chunk-DNJI65VQ.js.map +1 -0
  102. package/dist/chunk-DOUDJU4P.js +63 -0
  103. package/dist/chunk-DOUDJU4P.js.map +1 -0
  104. package/dist/chunk-DRCMGIQ6.js +64 -0
  105. package/dist/chunk-DRCMGIQ6.js.map +1 -0
  106. package/dist/chunk-DZOBXK2S.js +28 -0
  107. package/dist/chunk-DZOBXK2S.js.map +1 -0
  108. package/dist/chunk-EN4OJCEF.js +54 -0
  109. package/dist/chunk-EN4OJCEF.js.map +1 -0
  110. package/dist/chunk-EVHZFYWX.js +33 -0
  111. package/dist/chunk-EVHZFYWX.js.map +1 -0
  112. package/dist/chunk-G2VKWNZA.js +53 -0
  113. package/dist/chunk-G2VKWNZA.js.map +1 -0
  114. package/dist/chunk-GTM2DE4C.js +156 -0
  115. package/dist/chunk-GTM2DE4C.js.map +1 -0
  116. package/dist/chunk-H3ZVGTJM.js +165 -0
  117. package/dist/chunk-H3ZVGTJM.js.map +1 -0
  118. package/dist/chunk-HWAWUEHC.js +28 -0
  119. package/dist/chunk-HWAWUEHC.js.map +1 -0
  120. package/dist/chunk-HWJVRTWO.js +36 -0
  121. package/dist/chunk-HWJVRTWO.js.map +1 -0
  122. package/dist/chunk-ILADNTUB.js +77 -0
  123. package/dist/chunk-ILADNTUB.js.map +1 -0
  124. package/dist/chunk-IUPVQWO5.js +31 -0
  125. package/dist/chunk-IUPVQWO5.js.map +1 -0
  126. package/dist/chunk-JFOW2DI5.js +43 -0
  127. package/dist/chunk-JFOW2DI5.js.map +1 -0
  128. package/dist/chunk-JRFSUVSO.js +66 -0
  129. package/dist/chunk-JRFSUVSO.js.map +1 -0
  130. package/dist/chunk-KI6OTVID.js +91 -0
  131. package/dist/chunk-KI6OTVID.js.map +1 -0
  132. package/dist/chunk-LUM2YJBH.js +73 -0
  133. package/dist/chunk-LUM2YJBH.js.map +1 -0
  134. package/dist/chunk-NHPISZWS.js +71 -0
  135. package/dist/chunk-NHPISZWS.js.map +1 -0
  136. package/dist/chunk-NOLWJJHT.js +52 -0
  137. package/dist/chunk-NOLWJJHT.js.map +1 -0
  138. package/dist/chunk-NPVINX3Q.js +20 -0
  139. package/dist/chunk-NPVINX3Q.js.map +1 -0
  140. package/dist/chunk-NSMU66ZX.js +47 -0
  141. package/dist/chunk-NSMU66ZX.js.map +1 -0
  142. package/dist/chunk-O5SWPHUQ.js +79 -0
  143. package/dist/chunk-O5SWPHUQ.js.map +1 -0
  144. package/dist/chunk-OGVSZ7NV.js +53 -0
  145. package/dist/chunk-OGVSZ7NV.js.map +1 -0
  146. package/dist/chunk-OLHMMFQ7.js +43 -0
  147. package/dist/chunk-OLHMMFQ7.js.map +1 -0
  148. package/dist/chunk-ONMTHBZ4.js +54 -0
  149. package/dist/chunk-ONMTHBZ4.js.map +1 -0
  150. package/dist/chunk-OVSIOZHJ.js +56 -0
  151. package/dist/chunk-OVSIOZHJ.js.map +1 -0
  152. package/dist/chunk-Q54CVE3W.js +154 -0
  153. package/dist/chunk-Q54CVE3W.js.map +1 -0
  154. package/dist/chunk-QEHTPQHL.js +35 -0
  155. package/dist/chunk-QEHTPQHL.js.map +1 -0
  156. package/dist/chunk-QEIEWGHA.js +62 -0
  157. package/dist/chunk-QEIEWGHA.js.map +1 -0
  158. package/dist/chunk-QQHBEACI.js +88 -0
  159. package/dist/chunk-QQHBEACI.js.map +1 -0
  160. package/dist/chunk-RJTDQOT2.js +73 -0
  161. package/dist/chunk-RJTDQOT2.js.map +1 -0
  162. package/dist/chunk-RQ3RXKAZ.js +203 -0
  163. package/dist/chunk-RQ3RXKAZ.js.map +1 -0
  164. package/dist/chunk-RZK2S2OO.js +126 -0
  165. package/dist/chunk-RZK2S2OO.js.map +1 -0
  166. package/dist/chunk-SAP7JSSO.js +106 -0
  167. package/dist/chunk-SAP7JSSO.js.map +1 -0
  168. package/dist/chunk-T3TQPOVM.js +79 -0
  169. package/dist/chunk-T3TQPOVM.js.map +1 -0
  170. package/dist/chunk-T3UQ7G4T.js +58 -0
  171. package/dist/chunk-T3UQ7G4T.js.map +1 -0
  172. package/dist/chunk-T56TTOI6.js +53 -0
  173. package/dist/chunk-T56TTOI6.js.map +1 -0
  174. package/dist/chunk-T7EFDE2L.js +36 -0
  175. package/dist/chunk-T7EFDE2L.js.map +1 -0
  176. package/dist/chunk-VFS3V3VY.js +91 -0
  177. package/dist/chunk-VFS3V3VY.js.map +1 -0
  178. package/dist/chunk-VOARBYVQ.js +44 -0
  179. package/dist/chunk-VOARBYVQ.js.map +1 -0
  180. package/dist/chunk-WDANALHD.js +95 -0
  181. package/dist/chunk-WDANALHD.js.map +1 -0
  182. package/dist/chunk-WSQNPRGN.js +12 -0
  183. package/dist/chunk-WSQNPRGN.js.map +1 -0
  184. package/dist/chunk-YPP7QHYT.js +393 -0
  185. package/dist/chunk-YPP7QHYT.js.map +1 -0
  186. package/dist/chunk-YTU7BRDW.js +72 -0
  187. package/dist/chunk-YTU7BRDW.js.map +1 -0
  188. package/dist/chunk-YYWODLER.js +111 -0
  189. package/dist/chunk-YYWODLER.js.map +1 -0
  190. package/dist/chunk-ZOXO3G3I.js +50 -0
  191. package/dist/chunk-ZOXO3G3I.js.map +1 -0
  192. package/dist/chunk-ZTFOR3AN.js +79 -0
  193. package/dist/chunk-ZTFOR3AN.js.map +1 -0
  194. package/dist/code-block.d.ts +14 -0
  195. package/dist/code-block.js +5 -0
  196. package/dist/code-block.js.map +1 -0
  197. package/dist/combobox.d.ts +26 -0
  198. package/dist/combobox.js +5 -0
  199. package/dist/combobox.js.map +1 -0
  200. package/dist/command-menu.d.ts +52 -0
  201. package/dist/command-menu.js +7 -0
  202. package/dist/command-menu.js.map +1 -0
  203. package/dist/container.d.ts +9 -0
  204. package/dist/container.js +5 -0
  205. package/dist/container.js.map +1 -0
  206. package/dist/cta-band.d.ts +12 -0
  207. package/dist/cta-band.js +5 -0
  208. package/dist/cta-band.js.map +1 -0
  209. package/dist/data-table.d.ts +58 -0
  210. package/dist/data-table.js +12 -0
  211. package/dist/data-table.js.map +1 -0
  212. package/dist/date-picker.d.ts +20 -0
  213. package/dist/date-picker.js +5 -0
  214. package/dist/date-picker.js.map +1 -0
  215. package/dist/dialog.d.ts +21 -0
  216. package/dist/dialog.js +5 -0
  217. package/dist/dialog.js.map +1 -0
  218. package/dist/divider.d.ts +12 -0
  219. package/dist/divider.js +5 -0
  220. package/dist/divider.js.map +1 -0
  221. package/dist/docker-stack-card.d.ts +21 -0
  222. package/dist/docker-stack-card.js +6 -0
  223. package/dist/docker-stack-card.js.map +1 -0
  224. package/dist/donut.d.ts +15 -0
  225. package/dist/donut.js +5 -0
  226. package/dist/donut.js.map +1 -0
  227. package/dist/dropdown-menu.d.ts +15 -0
  228. package/dist/dropdown-menu.js +5 -0
  229. package/dist/dropdown-menu.js.map +1 -0
  230. package/dist/empty.d.ts +12 -0
  231. package/dist/empty.js +5 -0
  232. package/dist/empty.js.map +1 -0
  233. package/dist/feature-card.d.ts +11 -0
  234. package/dist/feature-card.js +6 -0
  235. package/dist/feature-card.js.map +1 -0
  236. package/dist/file-upload.d.ts +20 -0
  237. package/dist/file-upload.js +5 -0
  238. package/dist/file-upload.js.map +1 -0
  239. package/dist/footer.d.ts +35 -0
  240. package/dist/footer.js +6 -0
  241. package/dist/footer.js.map +1 -0
  242. package/dist/form-row.d.ts +19 -0
  243. package/dist/form-row.js +5 -0
  244. package/dist/form-row.js.map +1 -0
  245. package/dist/glow-card.d.ts +14 -0
  246. package/dist/glow-card.js +5 -0
  247. package/dist/glow-card.js.map +1 -0
  248. package/dist/hero-block.d.ts +16 -0
  249. package/dist/hero-block.js +7 -0
  250. package/dist/hero-block.js.map +1 -0
  251. package/dist/host-card.d.ts +27 -0
  252. package/dist/host-card.js +6 -0
  253. package/dist/host-card.js.map +1 -0
  254. package/dist/incident-card.d.ts +23 -0
  255. package/dist/incident-card.js +5 -0
  256. package/dist/incident-card.js.map +1 -0
  257. package/dist/index.d.ts +77 -960
  258. package/dist/index.js +69 -3812
  259. package/dist/index.js.map +1 -1
  260. package/dist/input.d.ts +10 -0
  261. package/dist/input.js +5 -0
  262. package/dist/input.js.map +1 -0
  263. package/dist/kbd.d.ts +24 -0
  264. package/dist/kbd.js +5 -0
  265. package/dist/kbd.js.map +1 -0
  266. package/dist/log-viewer.d.ts +35 -0
  267. package/dist/log-viewer.js +5 -0
  268. package/dist/log-viewer.js.map +1 -0
  269. package/dist/meter.d.ts +23 -0
  270. package/dist/meter.js +5 -0
  271. package/dist/meter.js.map +1 -0
  272. package/dist/monogram.d.ts +20 -0
  273. package/dist/monogram.js +5 -0
  274. package/dist/monogram.js.map +1 -0
  275. package/dist/noir-glow-background.d.ts +56 -0
  276. package/dist/noir-glow-background.js +4 -0
  277. package/dist/noir-glow-background.js.map +1 -0
  278. package/dist/pagination.d.ts +16 -0
  279. package/dist/pagination.js +5 -0
  280. package/dist/pagination.js.map +1 -0
  281. package/dist/panel.d.ts +12 -0
  282. package/dist/panel.js +5 -0
  283. package/dist/panel.js.map +1 -0
  284. package/dist/password-input.d.ts +10 -0
  285. package/dist/password-input.js +5 -0
  286. package/dist/password-input.js.map +1 -0
  287. package/dist/pill.d.ts +17 -0
  288. package/dist/pill.js +5 -0
  289. package/dist/pill.js.map +1 -0
  290. package/dist/pricing-card.d.ts +20 -0
  291. package/dist/pricing-card.js +6 -0
  292. package/dist/pricing-card.js.map +1 -0
  293. package/dist/progress.d.ts +6 -0
  294. package/dist/progress.js +5 -0
  295. package/dist/progress.js.map +1 -0
  296. package/dist/radio-group.d.ts +18 -0
  297. package/dist/radio-group.js +5 -0
  298. package/dist/radio-group.js.map +1 -0
  299. package/dist/rollback-plan.d.ts +23 -0
  300. package/dist/rollback-plan.js +5 -0
  301. package/dist/rollback-plan.js.map +1 -0
  302. package/dist/segmented.d.ts +17 -0
  303. package/dist/segmented.js +5 -0
  304. package/dist/segmented.js.map +1 -0
  305. package/dist/select.d.ts +18 -0
  306. package/dist/select.js +5 -0
  307. package/dist/select.js.map +1 -0
  308. package/dist/service-health-card.d.ts +21 -0
  309. package/dist/service-health-card.js +6 -0
  310. package/dist/service-health-card.js.map +1 -0
  311. package/dist/sheet.d.ts +25 -0
  312. package/dist/sheet.js +5 -0
  313. package/dist/sheet.js.map +1 -0
  314. package/dist/skeleton.d.ts +13 -0
  315. package/dist/skeleton.js +5 -0
  316. package/dist/skeleton.js.map +1 -0
  317. package/dist/slider.d.ts +12 -0
  318. package/dist/slider.js +5 -0
  319. package/dist/slider.js.map +1 -0
  320. package/dist/sparkline.d.ts +16 -0
  321. package/dist/sparkline.js +5 -0
  322. package/dist/sparkline.js.map +1 -0
  323. package/dist/stat-card.d.ts +15 -0
  324. package/dist/stat-card.js +5 -0
  325. package/dist/stat-card.js.map +1 -0
  326. package/dist/status-dot.d.ts +13 -0
  327. package/dist/status-dot.js +5 -0
  328. package/dist/status-dot.js.map +1 -0
  329. package/dist/stepper.d.ts +16 -0
  330. package/dist/stepper.js +5 -0
  331. package/dist/stepper.js.map +1 -0
  332. package/dist/switch.d.ts +9 -0
  333. package/dist/switch.js +5 -0
  334. package/dist/switch.js.map +1 -0
  335. package/dist/tabs.d.ts +9 -0
  336. package/dist/tabs.js +5 -0
  337. package/dist/tabs.js.map +1 -0
  338. package/dist/tag-input.d.ts +20 -0
  339. package/dist/tag-input.js +5 -0
  340. package/dist/tag-input.js.map +1 -0
  341. package/dist/textarea.d.ts +10 -0
  342. package/dist/textarea.js +5 -0
  343. package/dist/textarea.js.map +1 -0
  344. package/dist/timeline.d.ts +30 -0
  345. package/dist/timeline.js +5 -0
  346. package/dist/timeline.js.map +1 -0
  347. package/dist/toaster.d.ts +10 -0
  348. package/dist/toaster.js +4 -0
  349. package/dist/toaster.js.map +1 -0
  350. package/dist/tooltip.d.ts +12 -0
  351. package/dist/tooltip.js +5 -0
  352. package/dist/tooltip.js.map +1 -0
  353. package/dist/utils.d.ts +5 -0
  354. package/dist/utils.js +4 -0
  355. package/dist/utils.js.map +1 -0
  356. package/globals-layers.css +1019 -0
  357. package/globals-v3.css +17 -0
  358. package/globals-v4.css +2 -0
  359. package/globals.css +12 -939
  360. package/package.json +85 -17
  361. package/registry.json +936 -0
  362. package/tailwind.css +9 -0
  363. package/tokens.css +20 -0
  364. package/tollerud-avatar-full.png +0 -0
  365. package/dist/index.cjs +0 -3938
  366. package/dist/index.cjs.map +0 -1
  367. package/dist/index.d.cts +0 -960
  368. /package/{tia-full-figure.svg → tollerud-avatar-full.svg} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/AreaChart.tsx"],"names":[],"mappings":";;;;AAQA,IAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,SAAS,GAAA,EAAK,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACpD,IAAA,MAAM,UAAA,GAAa,KAAA,EAAM,CAAE,OAAA,CAAQ,MAAM,EAAE,CAAA;AAC3C,IAAA,MAAM,CAAA,GAAI,GAAA;AACV,IAAA,MAAM,CAAA,GAAI,MAAA;AACV,IAAA,MAAM,GAAA,GAAM,CAAA;AACZ,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,IAAI,CAAA,GAAI,GAAA;AAChC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,MAAM,CAAC,CAAA;AAC/B,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,GAAS,GAAG,CAAC,CAAA;AACxC,IAAA,MAAM,IAAI,CAAC,CAAA,KAAc,MAAO,CAAA,GAAI,IAAA,IAAS,IAAI,GAAA,GAAM,CAAA,CAAA;AACvD,IAAA,MAAM,CAAA,GAAI,CAAC,CAAA,KAAc,CAAA,GAAI,GAAA,GAAA,CAAQ,CAAA,GAAI,GAAA,KAAQ,GAAA,GAAM,GAAA,IAAO,CAAA,CAAA,IAAO,CAAA,GAAI,GAAA,GAAM,CAAA,CAAA;AAC/E,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,MAAM,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,IAAI,CAAA,CAAE,CAAC,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,GAAG,CAAA;AAC3D,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,CAAA,GAAI,GAAG,CAAA,CAAA,EAAI,IAAI,GAAG,CAAA,CAAA;AAE5D,IAAA,uBACE,GAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,QAAA,EAAU,SAAS,CAAA,EAAI,GAAG,KAAA,EACrD,QAAA,kBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,CAAA,IAAA,EAAO,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AAAA,QACtB,SAAA,EAAU,QAAA;AAAA,QACV,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,QAChB,mBAAA,EAAoB,MAAA;AAAA,QACpB,IAAA,EAAK,KAAA;AAAA,QACL,aAAA,EAAY,MAAA;AAAA,QAEZ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,gBAAA,EAAA,EAAe,EAAA,EAAI,UAAA,EAAY,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EACtD,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAK,MAAA,EAAO,IAAA,EAAK,SAAA,EAAU,SAAA,EAAU,aAAY,MAAA,EAAO,CAAA;AAAA,gCACxD,MAAA,EAAA,EAAK,MAAA,EAAO,QAAO,SAAA,EAAU,SAAA,EAAU,aAAY,GAAA,EAAI;AAAA,WAAA,EAC1D,CAAA,EACF,CAAA;AAAA,UACC,CAAC,MAAM,GAAA,EAAK,IAAI,EAAE,GAAA,CAAI,CAAC,GAAG,CAAA,qBACzB,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cAEC,EAAA,EAAI,GAAA;AAAA,cACJ,IAAI,CAAA,GAAI,GAAA;AAAA,cACR,IAAI,CAAA,GAAI,CAAA;AAAA,cACR,IAAI,CAAA,GAAI,CAAA;AAAA,cACR,MAAA,EAAO,mBAAA;AAAA,cACP,WAAA,EAAY;AAAA,aAAA;AAAA,YANP;AAAA,WAQR,CAAA;AAAA,8BACA,SAAA,EAAA,EAAQ,MAAA,EAAQ,MAAM,IAAA,EAAM,CAAA,KAAA,EAAQ,UAAU,CAAA,CAAA,CAAA,EAAK,CAAA;AAAA,0BACpD,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,MAAA,EAAQ,IAAA;AAAA,cACR,IAAA,EAAK,MAAA;AAAA,cACL,MAAA,EAAO,SAAA;AAAA,cACP,WAAA,EAAY,GAAA;AAAA,cACZ,aAAA,EAAc,OAAA;AAAA,cACd,cAAA,EAAe;AAAA;AAAA,WACjB;AAAA,UACC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACZ,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,EAAA,EAAI,EAAE,CAAC,CAAA;AAAA,cACP,EAAA,EAAI,EAAE,CAAC,CAAA;AAAA,cACP,CAAA,EAAE,KAAA;AAAA,cACF,IAAA,EAAK,aAAA;AAAA,cACL,MAAA,EAAO,SAAA;AAAA,cACP,WAAA,EAAY;AAAA,aAAA;AAAA,YANP;AAAA,WAQR;AAAA;AAAA;AAAA,KACH,EACF,CAAA;AAAA,EAEJ;AACF;AACA,SAAA,CAAU,WAAA,GAAc,WAAA","file":"chunk-6PZKU6ZL.js","sourcesContent":["import { type HTMLAttributes, forwardRef, useId } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface AreaChartProps extends HTMLAttributes<HTMLDivElement> {\n data: number[]\n height?: number\n}\n\nconst AreaChart = forwardRef<HTMLDivElement, AreaChartProps>(\n ({ className, data, height = 180, ...props }, ref) => {\n const gradientId = useId().replace(/:/g, '')\n const w = 520\n const h = height\n const pad = 8\n const max = Math.max(...data) * 1.1\n const min = Math.min(...data, 0)\n const span = Math.max(data.length - 1, 1)\n const x = (i: number) => pad + (i / span) * (w - pad * 2)\n const y = (v: number) => h - pad - ((v - min) / (max - min || 1)) * (h - pad * 2)\n const line = data.map((v, i) => `${x(i)},${y(v)}`).join(' ')\n const area = `${pad},${h - pad} ${line} ${w - pad},${h - pad}`\n\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n <svg\n viewBox={`0 0 ${w} ${h}`}\n className=\"w-full\"\n style={{ height }}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-hidden=\"true\"\n >\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#E8D500\" stopOpacity=\"0.30\" />\n <stop offset=\"100%\" stopColor=\"#E8D500\" stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n {[0.25, 0.5, 0.75].map((g, i) => (\n <line\n key={i}\n x1={pad}\n x2={w - pad}\n y1={h * g}\n y2={h * g}\n stroke=\"var(--chart-grid)\"\n strokeWidth=\"1\"\n />\n ))}\n <polygon points={area} fill={`url(#${gradientId})`} />\n <polyline\n points={line}\n fill=\"none\"\n stroke=\"#E8D500\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {data.map((v, i) => (\n <circle\n key={i}\n cx={x(i)}\n cy={y(v)}\n r=\"2.5\"\n fill=\"var(--card)\"\n stroke=\"#E8D500\"\n strokeWidth=\"1.5\"\n />\n ))}\n </svg>\n </div>\n )\n }\n)\nAreaChart.displayName = 'AreaChart'\n\nexport { AreaChart }\n"]}
@@ -0,0 +1,75 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef, useId } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var RadioGroup = forwardRef(
7
+ ({ label, error, children, className }, ref) => {
8
+ return /* @__PURE__ */ jsxs("fieldset", { ref, className: cn("flex flex-col gap-1", className), children: [
9
+ label && /* @__PURE__ */ jsx("legend", { className: "text-xs font-medium text-tollerud-text-muted mb-1", children: label }),
10
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children }),
11
+ error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error mt-0.5", children: error })
12
+ ] });
13
+ }
14
+ );
15
+ RadioGroup.displayName = "RadioGroup";
16
+ var Radio = forwardRef(
17
+ ({ className, label, id: idProp, ...props }, ref) => {
18
+ const autoId = useId();
19
+ const id = idProp ?? autoId;
20
+ return /* @__PURE__ */ jsxs(
21
+ "label",
22
+ {
23
+ htmlFor: id,
24
+ className: cn(
25
+ "inline-flex items-center gap-2 cursor-pointer select-none group",
26
+ "text-sm text-tollerud-text-primary",
27
+ props.disabled && "opacity-50 pointer-events-none",
28
+ className
29
+ ),
30
+ children: [
31
+ /* @__PURE__ */ jsxs("span", { className: "relative flex items-center justify-center", children: [
32
+ /* @__PURE__ */ jsx(
33
+ "input",
34
+ {
35
+ ref,
36
+ id,
37
+ type: "radio",
38
+ className: "peer sr-only",
39
+ ...props
40
+ }
41
+ ),
42
+ /* @__PURE__ */ jsx(
43
+ "span",
44
+ {
45
+ className: cn(
46
+ "h-4 w-4 rounded-full border transition-all duration-[150ms]",
47
+ "bg-tollerud-surface-raised border-tollerud-border",
48
+ "peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow",
49
+ "peer-checked:border-tollerud-yellow",
50
+ "group-hover:border-tollerud-text-secondary",
51
+ "flex items-center justify-center"
52
+ ),
53
+ children: /* @__PURE__ */ jsx(
54
+ "span",
55
+ {
56
+ className: cn(
57
+ "h-2 w-2 rounded-full bg-tollerud-yellow transition-opacity duration-[150ms]",
58
+ props.checked ? "opacity-100" : "opacity-0"
59
+ )
60
+ }
61
+ )
62
+ }
63
+ )
64
+ ] }),
65
+ label && /* @__PURE__ */ jsx("span", { children: label })
66
+ ]
67
+ }
68
+ );
69
+ }
70
+ );
71
+ Radio.displayName = "Radio";
72
+
73
+ export { Radio, RadioGroup };
74
+ //# sourceMappingURL=chunk-6SKTH45H.js.map
75
+ //# sourceMappingURL=chunk-6SKTH45H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/RadioGroup.tsx"],"names":[],"mappings":";;;;AAcA,IAAM,UAAA,GAAa,UAAA;AAAA,EACjB,CAAC,EAAE,KAAA,EAAO,OAAO,QAAA,EAAU,SAAA,IAAa,GAAA,KAAQ;AAC9C,IAAA,4BACG,UAAA,EAAA,EAAS,GAAA,EAAU,WAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EAC/D,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAU,mDAAA,EACf,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,sBAEF,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAS,CAAA;AAAA,MAC9C,KAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCAAsC,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EAE7D,CAAA;AAAA,EAEJ;AACF;AACA,UAAA,CAAW,WAAA,GAAc,YAAA;AAMzB,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,IAAI,MAAA,EAAQ,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACnD,IAAA,MAAM,SAAS,KAAA,EAAM;AACrB,IAAA,MAAM,KAAK,MAAA,IAAU,MAAA;AAErB,IAAA,uBACE,IAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,EAAA;AAAA,QACT,SAAA,EAAW,EAAA;AAAA,UACT,iEAAA;AAAA,UACA,oCAAA;AAAA,UACA,MAAM,QAAA,IAAY,gCAAA;AAAA,UAClB;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2CAAA,EACd,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,GAAA;AAAA,gBACA,EAAA;AAAA,gBACA,IAAA,EAAK,OAAA;AAAA,gBACL,SAAA,EAAU,cAAA;AAAA,gBACT,GAAG;AAAA;AAAA,aACN;AAAA,4BAEA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAW,EAAA;AAAA,kBACT,6DAAA;AAAA,kBACA,mDAAA;AAAA,kBACA,yEAAA;AAAA,kBACA,qCAAA;AAAA,kBACA,4CAAA;AAAA,kBACA;AAAA,iBACF;AAAA,gBAGA,QAAA,kBAAA,GAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,6EAAA;AAAA,sBACA,KAAA,CAAM,UAAU,aAAA,GAAgB;AAAA;AAClC;AAAA;AACF;AAAA;AACF,WAAA,EACF,CAAA;AAAA,UACC,KAAA,oBAAS,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,KACzB;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-6SKTH45H.js","sourcesContent":["'use client'\n\nimport { type InputHTMLAttributes, forwardRef, useId } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface RadioGroupProps {\n /** Group label */\n label?: string\n /** Error message */\n error?: string\n children?: React.ReactNode\n className?: string\n}\n\nconst RadioGroup = forwardRef<HTMLFieldSetElement, RadioGroupProps>(\n ({ label, error, children, className }, ref) => {\n return (\n <fieldset ref={ref} className={cn('flex flex-col gap-1', className)}>\n {label && (\n <legend className=\"text-xs font-medium text-tollerud-text-muted mb-1\">\n {label}\n </legend>\n )}\n <div className=\"flex flex-col gap-2\">{children}</div>\n {error && (\n <p className=\"text-xs text-tollerud-error mt-0.5\">{error}</p>\n )}\n </fieldset>\n )\n }\n)\nRadioGroup.displayName = 'RadioGroup'\n\nexport interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: string\n}\n\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(\n ({ className, label, id: idProp, ...props }, ref) => {\n const autoId = useId()\n const id = idProp ?? autoId\n\n return (\n <label\n htmlFor={id}\n className={cn(\n 'inline-flex items-center gap-2 cursor-pointer select-none group',\n 'text-sm text-tollerud-text-primary',\n props.disabled && 'opacity-50 pointer-events-none',\n className\n )}\n >\n <span className=\"relative flex items-center justify-center\">\n <input\n ref={ref}\n id={id}\n type=\"radio\"\n className=\"peer sr-only\"\n {...props}\n />\n {/* Custom radio circle */}\n <span\n className={cn(\n 'h-4 w-4 rounded-full border transition-all duration-[150ms]',\n 'bg-tollerud-surface-raised border-tollerud-border',\n 'peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow',\n 'peer-checked:border-tollerud-yellow',\n 'group-hover:border-tollerud-text-secondary',\n 'flex items-center justify-center'\n )}\n >\n {/* Inner dot */}\n <span\n className={cn(\n 'h-2 w-2 rounded-full bg-tollerud-yellow transition-opacity duration-[150ms]',\n props.checked ? 'opacity-100' : 'opacity-0'\n )}\n />\n </span>\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n }\n)\nRadio.displayName = 'Radio'\n\nexport { RadioGroup, Radio }"]}
@@ -0,0 +1,77 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import * as React from 'react';
4
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ var TooltipProvider = TooltipPrimitive.Provider;
8
+ var TooltipContext = React.createContext(null);
9
+ function Tooltip({
10
+ children,
11
+ defaultOpen,
12
+ open: controlledOpen,
13
+ onOpenChange: controlledOnOpenChange,
14
+ ...props
15
+ }) {
16
+ const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false);
17
+ const isControlled = controlledOpen !== void 0;
18
+ const open = isControlled ? controlledOpen : internalOpen;
19
+ const setOpen = isControlled ? controlledOnOpenChange ?? setInternalOpen : setInternalOpen;
20
+ return /* @__PURE__ */ jsx(TooltipContext.Provider, { value: { open, setOpen }, children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { open, onOpenChange: (v) => setOpen(v), ...props, children }) });
21
+ }
22
+ Tooltip.displayName = "Tooltip";
23
+ var TooltipTrigger = React.forwardRef(({ onClick, onTouchStart, children, ...props }, ref) => {
24
+ const ctx = React.useContext(TooltipContext);
25
+ const touchFired = React.useRef(false);
26
+ return /* @__PURE__ */ jsx(
27
+ TooltipPrimitive.Trigger,
28
+ {
29
+ ref,
30
+ onClick: (e) => {
31
+ if (touchFired.current) {
32
+ touchFired.current = false;
33
+ return;
34
+ }
35
+ if (ctx) {
36
+ ctx.setOpen(!ctx.open);
37
+ }
38
+ onClick?.(e);
39
+ },
40
+ onTouchStart: (e) => {
41
+ touchFired.current = true;
42
+ if (ctx && !ctx.open) {
43
+ ctx.setOpen(true);
44
+ }
45
+ onTouchStart?.(e);
46
+ },
47
+ ...props,
48
+ children
49
+ }
50
+ );
51
+ });
52
+ TooltipTrigger.displayName = "TooltipTrigger";
53
+ var TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
54
+ TooltipPrimitive.Content,
55
+ {
56
+ ref,
57
+ sideOffset,
58
+ className: cn(
59
+ "z-50 overflow-hidden rounded-md border border-tollerud-border/30",
60
+ "bg-tollerud-noir-800 px-3 py-1.5 text-xs text-tollerud-foreground",
61
+ "shadow-md",
62
+ "animate-in fade-in-0 zoom-in-95",
63
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
64
+ "data-[side=bottom]:slide-in-from-top-1",
65
+ "data-[side=left]:slide-in-from-right-1",
66
+ "data-[side=right]:slide-in-from-left-1",
67
+ "data-[side=top]:slide-in-from-bottom-1",
68
+ className
69
+ ),
70
+ ...props
71
+ }
72
+ ));
73
+ TooltipContent.displayName = "TooltipContent";
74
+
75
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
76
+ //# sourceMappingURL=chunk-6UXW5YUC.js.map
77
+ //# sourceMappingURL=chunk-6UXW5YUC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Tooltip.tsx"],"names":[],"mappings":";;;;;AAMA,IAAM,eAAA,GAAmC,gBAAA,CAAA;AAYzC,IAAM,cAAA,GAAuB,oBAA0C,IAAI,CAAA;AAE3E,SAAS,OAAA,CAAQ;AAAA,EACf,QAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA,EAAM,cAAA;AAAA,EACN,YAAA,EAAc,sBAAA;AAAA,EACd,GAAG;AACL,CAAA,EAAiE;AAC/D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAU,KAAA,CAAA,QAAA,CAAS,eAAe,KAAK,CAAA;AAC3E,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,IAAA,GAAO,eAAe,cAAA,GAAiB,YAAA;AAC7C,EAAA,MAAM,OAAA,GAAU,YAAA,GAAgB,sBAAA,IAA0B,eAAA,GAAmB,eAAA;AAE7E,EAAA,uBACE,GAAA,CAAC,eAAe,QAAA,EAAf,EAAwB,OAAO,EAAE,IAAA,EAAM,OAAA,EAAQ,EAC9C,QAAA,kBAAA,GAAA,CAAkB,gBAAA,CAAA,IAAA,EAAjB,EAAsB,IAAA,EAAY,YAAA,EAAc,CAAC,CAAA,KAAe,OAAA,CAAQ,CAAC,CAAA,EAAI,GAAG,KAAA,EAC9E,QAAA,EACH,CAAA,EACF,CAAA;AAEJ;AACA,OAAA,CAAQ,WAAA,GAAc,SAAA;AAEtB,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA,CAG3B,CAAC,EAAE,OAAA,EAAS,cAAc,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACxD,EAAA,MAAM,GAAA,GAAY,iBAAW,cAAc,CAAA;AAC3C,EAAA,MAAM,UAAA,GAAmB,aAAO,KAAK,CAAA;AAErC,EAAA,uBACE,GAAA;AAAA,IAAkB,gBAAA,CAAA,OAAA;AAAA,IAAjB;AAAA,MACC,GAAA;AAAA,MACA,OAAA,EAAS,CAAC,CAAA,KAAM;AAEd,QAAA,IAAI,WAAW,OAAA,EAAS;AACtB,UAAA,UAAA,CAAW,OAAA,GAAU,KAAA;AACrB,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,GAAA,EAAK;AACP,UAAA,GAAA,CAAI,OAAA,CAAQ,CAAC,GAAA,CAAI,IAAI,CAAA;AAAA,QACvB;AACA,QAAA,OAAA,GAAU,CAAC,CAAA;AAAA,MACb,CAAA;AAAA,MACA,YAAA,EAAc,CAAC,CAAA,KAAM;AACnB,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAErB,QAAA,IAAI,GAAA,IAAO,CAAC,GAAA,CAAI,IAAA,EAAM;AACpB,UAAA,GAAA,CAAI,QAAQ,IAAI,CAAA;AAAA,QAClB;AACA,QAAA,YAAA,GAAe,CAAC,CAAA;AAAA,MAClB,CAAA;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ,CAAC;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA;AAE7B,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA,CAG3B,CAAC,EAAE,SAAA,EAAW,aAAa,CAAA,EAAG,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1C,GAAA;AAAA,EAAkB,gBAAA,CAAA,OAAA;AAAA,EAAjB;AAAA,IACC,GAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,kEAAA;AAAA,MACA,mEAAA;AAAA,MACA,WAAA;AAAA,MACA,iCAAA;AAAA,MACA,gGAAA;AAAA,MACA,wCAAA;AAAA,MACA,wCAAA;AAAA,MACA,wCAAA;AAAA,MACA,wCAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"chunk-6UXW5YUC.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport { cn } from '@/lib/utils'\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\n/* ── Mobile-friendly Tooltip ──\n Opens on hover (desktop) AND on click/tap (mobile).\n Uses React context so the Trigger can toggle Root's open state.\n Closes on second click/tap or click outside. */\n\ntype TooltipContextValue = {\n open: boolean\n setOpen: (open: boolean) => void\n}\n\nconst TooltipContext = React.createContext<TooltipContextValue | null>(null)\n\nfunction Tooltip({\n children,\n defaultOpen,\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n ...props\n}: React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>) {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const isControlled = controlledOpen !== undefined\n const open = isControlled ? controlledOpen : internalOpen\n const setOpen = isControlled ? (controlledOnOpenChange ?? setInternalOpen) : setInternalOpen\n\n return (\n <TooltipContext.Provider value={{ open, setOpen }}>\n <TooltipPrimitive.Root open={open} onOpenChange={(v: boolean) => setOpen(v)} {...props}>\n {children}\n </TooltipPrimitive.Root>\n </TooltipContext.Provider>\n )\n}\nTooltip.displayName = 'Tooltip'\n\nconst TooltipTrigger = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>\n>(({ onClick, onTouchStart, children, ...props }, ref) => {\n const ctx = React.useContext(TooltipContext)\n const touchFired = React.useRef(false)\n\n return (\n <TooltipPrimitive.Trigger\n ref={ref}\n onClick={(e) => {\n // Skip click if this was triggered by a touch (already handled)\n if (touchFired.current) {\n touchFired.current = false\n return\n }\n // Toggle tooltip on click — covers mobile where hover doesn't fire\n if (ctx) {\n ctx.setOpen(!ctx.open)\n }\n onClick?.(e)\n }}\n onTouchStart={(e) => {\n touchFired.current = true\n // Open on touch for mobile\n if (ctx && !ctx.open) {\n ctx.setOpen(true)\n }\n onTouchStart?.(e)\n }}\n {...props}\n >\n {children}\n </TooltipPrimitive.Trigger>\n )\n})\nTooltipTrigger.displayName = 'TooltipTrigger'\n\nconst TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 overflow-hidden rounded-md border border-tollerud-border/30',\n 'bg-tollerud-noir-800 px-3 py-1.5 text-xs text-tollerud-foreground',\n 'shadow-md',\n 'animate-in fade-in-0 zoom-in-95',\n 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',\n 'data-[side=bottom]:slide-in-from-top-1',\n 'data-[side=left]:slide-in-from-right-1',\n 'data-[side=right]:slide-in-from-left-1',\n 'data-[side=top]:slide-in-from-bottom-1',\n className\n )}\n {...props}\n />\n))\nTooltipContent.displayName = 'TooltipContent'\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }"]}
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+ import { StatusDot } from './chunk-NHPISZWS.js';
3
+ import { cn } from './chunk-WSQNPRGN.js';
4
+ import { forwardRef } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var ServiceHealthCard = forwardRef(
8
+ ({ className, service, status = "online", uptime, responseTime, version, loading, ...props }, ref) => {
9
+ return /* @__PURE__ */ jsxs(
10
+ "div",
11
+ {
12
+ ref,
13
+ className: cn(
14
+ "rounded-lg border bg-tollerud-surface-raised p-4",
15
+ "transition-[border-color] duration-[150ms]",
16
+ status === "offline" && "border-tollerud-error/40",
17
+ status === "warning" && "border-tollerud-yellow/30",
18
+ status === "online" && "border-tollerud-border hover:border-tollerud-noir-500",
19
+ status === "idle" && "border-tollerud-border opacity-60",
20
+ loading && "animate-pulse",
21
+ className
22
+ ),
23
+ ...props,
24
+ children: [
25
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
26
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-tollerud-foreground truncate", children: service }),
27
+ /* @__PURE__ */ jsx(StatusDot, { status })
28
+ ] }),
29
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-x-4 gap-y-1 text-xs text-tollerud-text-muted", children: [
30
+ uptime && /* @__PURE__ */ jsxs("span", { children: [
31
+ "Uptime: ",
32
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: uptime })
33
+ ] }),
34
+ responseTime && /* @__PURE__ */ jsxs("span", { children: [
35
+ "Response: ",
36
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: responseTime })
37
+ ] }),
38
+ version && /* @__PURE__ */ jsxs("span", { children: [
39
+ "Version: ",
40
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: version })
41
+ ] })
42
+ ] })
43
+ ]
44
+ }
45
+ );
46
+ }
47
+ );
48
+ ServiceHealthCard.displayName = "ServiceHealthCard";
49
+
50
+ export { ServiceHealthCard };
51
+ //# sourceMappingURL=chunk-7EP2T3OW.js.map
52
+ //# sourceMappingURL=chunk-7EP2T3OW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/ServiceHealthCard.tsx"],"names":[],"mappings":";;;;;AAmBA,IAAM,iBAAA,GAAoB,UAAA;AAAA,EACxB,CAAC,EAAE,SAAA,EAAW,OAAA,EAAS,MAAA,GAAS,QAAA,EAAU,MAAA,EAAQ,YAAA,EAAc,OAAA,EAAS,OAAA,EAAS,GAAG,KAAA,IAAS,GAAA,KAAQ;AACpG,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,kDAAA;AAAA,UACA,4CAAA;AAAA,UACA,WAAW,SAAA,IAAa,0BAAA;AAAA,UACxB,WAAW,SAAA,IAAa,2BAAA;AAAA,UACxB,WAAW,QAAA,IAAY,uDAAA;AAAA,UACvB,WAAW,MAAA,IAAU,mCAAA;AAAA,UACrB,OAAA,IAAW,eAAA;AAAA,UACX;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wCAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yDAAA,EACb,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,4BACA,GAAA,CAAC,aAAU,MAAA,EAAgB;AAAA,WAAA,EAC7B,CAAA;AAAA,0BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iEAAA,EACZ,QAAA,EAAA;AAAA,YAAA,MAAA,yBAAW,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,UAAA;AAAA,8BAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,MAAA,EAAO;AAAA,aAAA,EAAO,CAAA;AAAA,YACtF,YAAA,yBAAiB,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,YAAA;AAAA,8BAAU,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,YAAA,EAAa;AAAA,aAAA,EAAO,CAAA;AAAA,YACpG,OAAA,yBAAY,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,WAAA;AAAA,8BAAS,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,OAAA,EAAQ;AAAA,aAAA,EAAO;AAAA,WAAA,EAC5F;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,iBAAA,CAAkB,WAAA,GAAc,mBAAA","file":"chunk-7EP2T3OW.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\nimport { StatusDot, type Status } from './StatusDot'\n\nexport interface ServiceHealthCardProps extends HTMLAttributes<HTMLDivElement> {\n /** Service name */\n service: string\n /** Health status */\n status?: Status\n /** Uptime string (e.g. '14d 3h') */\n uptime?: string\n /** Response time in ms */\n responseTime?: string\n /** Current version */\n version?: string\n /** Whether the card is in a loading state */\n loading?: boolean\n}\n\nconst ServiceHealthCard = forwardRef<HTMLDivElement, ServiceHealthCardProps>(\n ({ className, service, status = 'online', uptime, responseTime, version, loading, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'rounded-lg border bg-tollerud-surface-raised p-4',\n 'transition-[border-color] duration-[150ms]',\n status === 'offline' && 'border-tollerud-error/40',\n status === 'warning' && 'border-tollerud-yellow/30',\n status === 'online' && 'border-tollerud-border hover:border-tollerud-noir-500',\n status === 'idle' && 'border-tollerud-border opacity-60',\n loading && 'animate-pulse',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-semibold text-tollerud-foreground truncate\">\n {service}\n </span>\n <StatusDot status={status} />\n </div>\n <div className=\"flex flex-wrap gap-x-4 gap-y-1 text-xs text-tollerud-text-muted\">\n {uptime && <span>Uptime: <span className=\"text-tollerud-text-secondary\">{uptime}</span></span>}\n {responseTime && <span>Response: <span className=\"text-tollerud-text-secondary\">{responseTime}</span></span>}\n {version && <span>Version: <span className=\"text-tollerud-text-secondary\">{version}</span></span>}\n </div>\n </div>\n )\n }\n)\nServiceHealthCard.displayName = 'ServiceHealthCard'\n\nexport { ServiceHealthCard }\n"]}
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef, Fragment } from 'react';
4
+ import { ChevronRight } from 'lucide-react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ var Breadcrumb = forwardRef(
8
+ ({ className, items, separator, ...props }, ref) => {
9
+ return /* @__PURE__ */ jsx("nav", { ref, "aria-label": "Breadcrumb", className: cn("text-sm", className), ...props, children: /* @__PURE__ */ jsx("ol", { className: "flex items-center gap-1.5 flex-wrap", children: items.map((item, i) => {
10
+ const isLast = i === items.length - 1;
11
+ const content = !isLast && (item.href || item.onClick) ? /* @__PURE__ */ jsx(
12
+ "a",
13
+ {
14
+ href: item.href,
15
+ onClick: item.onClick,
16
+ className: "text-tollerud-text-secondary hover:text-tollerud-text-primary transition-colors duration-[150ms]",
17
+ children: item.label
18
+ }
19
+ ) : /* @__PURE__ */ jsx(
20
+ "span",
21
+ {
22
+ "aria-current": isLast ? "page" : void 0,
23
+ className: isLast ? "text-tollerud-text-primary font-medium" : "text-tollerud-text-secondary",
24
+ children: item.label
25
+ }
26
+ );
27
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
28
+ /* @__PURE__ */ jsx("li", { className: "flex items-center gap-1.5", children: content }),
29
+ !isLast && /* @__PURE__ */ jsx("li", { "aria-hidden": "true", className: "flex items-center text-tollerud-text-muted", children: separator ?? /* @__PURE__ */ jsx(ChevronRight, { size: 14 }) })
30
+ ] }, i);
31
+ }) }) });
32
+ }
33
+ );
34
+ Breadcrumb.displayName = "Breadcrumb";
35
+
36
+ export { Breadcrumb };
37
+ //# sourceMappingURL=chunk-7J5QXUQN.js.map
38
+ //# sourceMappingURL=chunk-7J5QXUQN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Breadcrumb.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,UAAA,GAAa,UAAA;AAAA,EACjB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAClD,IAAA,uBACE,GAAA,CAAC,SAAI,GAAA,EAAU,YAAA,EAAW,cAAa,SAAA,EAAW,EAAA,CAAG,WAAW,SAAS,CAAA,EAAI,GAAG,KAAA,EAC9E,QAAA,kBAAA,GAAA,CAAC,QAAG,SAAA,EAAU,qCAAA,EACX,gBAAM,GAAA,CAAI,CAAC,MAAM,CAAA,KAAM;AACtB,MAAA,MAAM,MAAA,GAAS,CAAA,KAAM,KAAA,CAAM,MAAA,GAAS,CAAA;AACpC,MAAA,MAAM,UACJ,CAAC,MAAA,KAAW,IAAA,CAAK,IAAA,IAAQ,KAAK,OAAA,CAAA,mBAC5B,GAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,SAAA,EAAU,kGAAA;AAAA,UAET,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,OACR,mBAEA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,cAAA,EAAc,SAAS,MAAA,GAAS,MAAA;AAAA,UAChC,SAAA,EAAW,SAAS,wCAAA,GAA2C,8BAAA;AAAA,UAE9D,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,OACR;AAGJ,MAAA,4BACG,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,2BAAA,EAA6B,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,QAClD,CAAC,MAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAG,aAAA,EAAY,MAAA,EAAO,SAAA,EAAU,4CAAA,EAC9B,QAAA,EAAA,SAAA,oBAAa,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAM,IAAI,CAAA,EACxC;AAAA,OAAA,EAAA,EALW,CAOf,CAAA;AAAA,IAEJ,CAAC,GACH,CAAA,EACF,CAAA;AAAA,EAEJ;AACF;AACA,UAAA,CAAW,WAAA,GAAc,YAAA","file":"chunk-7J5QXUQN.js","sourcesContent":["import { type HTMLAttributes, Fragment, forwardRef } from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface BreadcrumbItem {\n label: React.ReactNode\n href?: string\n onClick?: () => void\n}\n\nexport interface BreadcrumbProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {\n items: BreadcrumbItem[]\n /** Custom separator (defaults to a chevron) */\n separator?: React.ReactNode\n}\n\nconst Breadcrumb = forwardRef<HTMLElement, BreadcrumbProps>(\n ({ className, items, separator, ...props }, ref) => {\n return (\n <nav ref={ref} aria-label=\"Breadcrumb\" className={cn('text-sm', className)} {...props}>\n <ol className=\"flex items-center gap-1.5 flex-wrap\">\n {items.map((item, i) => {\n const isLast = i === items.length - 1\n const content =\n !isLast && (item.href || item.onClick) ? (\n <a\n href={item.href}\n onClick={item.onClick}\n className=\"text-tollerud-text-secondary hover:text-tollerud-text-primary transition-colors duration-[150ms]\"\n >\n {item.label}\n </a>\n ) : (\n <span\n aria-current={isLast ? 'page' : undefined}\n className={isLast ? 'text-tollerud-text-primary font-medium' : 'text-tollerud-text-secondary'}\n >\n {item.label}\n </span>\n )\n\n return (\n <Fragment key={i}>\n <li className=\"flex items-center gap-1.5\">{content}</li>\n {!isLast && (\n <li aria-hidden=\"true\" className=\"flex items-center text-tollerud-text-muted\">\n {separator ?? <ChevronRight size={14} />}\n </li>\n )}\n </Fragment>\n )\n })}\n </ol>\n </nav>\n )\n }\n)\nBreadcrumb.displayName = 'Breadcrumb'\n\nexport { Breadcrumb }\n"]}
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var meterTones = {
7
+ default: "bg-tollerud-yellow",
8
+ success: "bg-tollerud-success",
9
+ warning: "bg-tollerud-warning",
10
+ error: "bg-tollerud-error"
11
+ };
12
+ var Meter = forwardRef(
13
+ ({ className, value, max = 100, label, showValue, tone = "default", ...props }, ref) => {
14
+ const pct = Math.min(100, Math.max(0, value / max * 100));
15
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex flex-col gap-1.5", className), ...props, children: [
16
+ (label || showValue) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-xs", children: [
17
+ label && /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: label }),
18
+ showValue && /* @__PURE__ */ jsxs("span", { className: "text-tollerud-text-muted tabular-nums", children: [
19
+ Math.round(pct),
20
+ "%"
21
+ ] })
22
+ ] }),
23
+ /* @__PURE__ */ jsx(
24
+ "div",
25
+ {
26
+ role: "meter",
27
+ "aria-valuenow": value,
28
+ "aria-valuemin": 0,
29
+ "aria-valuemax": max,
30
+ className: "h-1.5 w-full overflow-hidden rounded-full bg-tollerud-surface-raised",
31
+ children: /* @__PURE__ */ jsx(
32
+ "div",
33
+ {
34
+ className: cn("h-full rounded-full transition-[width] duration-300", meterTones[tone]),
35
+ style: { width: `${pct}%` }
36
+ }
37
+ )
38
+ }
39
+ )
40
+ ] });
41
+ }
42
+ );
43
+ Meter.displayName = "Meter";
44
+
45
+ export { Meter };
46
+ //# sourceMappingURL=chunk-A6L5C3IJ.js.map
47
+ //# sourceMappingURL=chunk-A6L5C3IJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Meter.tsx"],"names":[],"mappings":";;;;AAGA,IAAM,UAAA,GAAa;AAAA,EACjB,OAAA,EAAS,oBAAA;AAAA,EACT,OAAA,EAAS,qBAAA;AAAA,EACT,OAAA,EAAS,qBAAA;AAAA,EACT,KAAA,EAAO;AACT,CAAA;AAcA,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,GAAA,GAAM,GAAA,EAAK,KAAA,EAAO,SAAA,EAAW,IAAA,GAAO,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AACtF,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,IAAI,CAAA,EAAI,KAAA,GAAQ,GAAA,GAAO,GAAG,CAAC,CAAA;AAE1D,IAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,uBAAA,EAAyB,SAAS,CAAA,EAAI,GAAG,KAAA,EAClE,QAAA,EAAA;AAAA,MAAA,CAAA,KAAA,IAAS,SAAA,qBACT,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAAA,EACZ,QAAA,EAAA;AAAA,QAAA,KAAA,oBAAS,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAC/D,SAAA,oBAAa,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uCAAA,EAAyC,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,UAAE;AAAA,SAAA,EAAC;AAAA,OAAA,EAC1F,CAAA;AAAA,sBAEF,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,OAAA;AAAA,UACL,eAAA,EAAe,KAAA;AAAA,UACf,eAAA,EAAe,CAAA;AAAA,UACf,eAAA,EAAe,GAAA;AAAA,UACf,SAAA,EAAU,sEAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA,CAAG,qDAAA,EAAuD,UAAA,CAAW,IAAI,CAAC,CAAA;AAAA,cACrF,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,EAAG,GAAG,CAAA,CAAA,CAAA;AAAI;AAAA;AAC5B;AAAA;AACF,KAAA,EACF,CAAA;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-A6L5C3IJ.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nconst meterTones = {\n default: 'bg-tollerud-yellow',\n success: 'bg-tollerud-success',\n warning: 'bg-tollerud-warning',\n error: 'bg-tollerud-error',\n} as const\n\nexport interface MeterProps extends HTMLAttributes<HTMLDivElement> {\n /** Current value */\n value: number\n /** Maximum value (defaults to 100) */\n max?: number\n /** Optional label rendered above the bar */\n label?: React.ReactNode\n /** Show the numeric value/percentage to the right of the label */\n showValue?: boolean\n tone?: keyof typeof meterTones\n}\n\nconst Meter = forwardRef<HTMLDivElement, MeterProps>(\n ({ className, value, max = 100, label, showValue, tone = 'default', ...props }, ref) => {\n const pct = Math.min(100, Math.max(0, (value / max) * 100))\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-1.5', className)} {...props}>\n {(label || showValue) && (\n <div className=\"flex items-center justify-between text-xs\">\n {label && <span className=\"text-tollerud-text-secondary\">{label}</span>}\n {showValue && <span className=\"text-tollerud-text-muted tabular-nums\">{Math.round(pct)}%</span>}\n </div>\n )}\n <div\n role=\"meter\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n className=\"h-1.5 w-full overflow-hidden rounded-full bg-tollerud-surface-raised\"\n >\n <div\n className={cn('h-full rounded-full transition-[width] duration-300', meterTones[tone])}\n style={{ width: `${pct}%` }}\n />\n </div>\n </div>\n )\n }\n)\nMeter.displayName = 'Meter'\n\nexport { Meter }\n"]}
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { Slot } from '@radix-ui/react-slot';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ var variants = {
8
+ primary: "bg-tollerud-yellow text-tollerud-black border-tollerud-yellow hover:bg-tollerud-yellow hover:shadow-tollerud-glow",
9
+ secondary: "bg-transparent text-tollerud-text-primary border-tollerud-border hover:border-tollerud-text-secondary hover:bg-tollerud-surface-hover",
10
+ ghost: "bg-transparent text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover",
11
+ destructive: "bg-tollerud-error text-white border-tollerud-error hover:shadow-[0_0_12px_rgba(239,68,68,0.3)]",
12
+ terminal: "font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]"
13
+ };
14
+ var variantLayers = {
15
+ primary: "tollerud-btn--primary",
16
+ secondary: "",
17
+ ghost: "",
18
+ destructive: "",
19
+ terminal: "tollerud-btn--terminal"
20
+ };
21
+ var sizes = {
22
+ sm: "px-3 py-1 text-sm",
23
+ md: "px-4 py-2 text-base",
24
+ lg: "px-6 py-3 text-lg"
25
+ };
26
+ function buttonVariants({ variant = "secondary", size = "md", className } = {}) {
27
+ return cn(
28
+ "tollerud-btn inline-flex items-center justify-center gap-2 font-semibold rounded transition-all duration-[150ms] focus-visible:outline-2 focus-visible:outline-tollerud-yellow focus-visible:outline-offset-2",
29
+ "border cursor-pointer",
30
+ "disabled:opacity-50 disabled:pointer-events-none",
31
+ variants[variant],
32
+ variantLayers[variant],
33
+ sizes[size],
34
+ className
35
+ );
36
+ }
37
+ var Button = forwardRef(
38
+ ({ className, variant = "secondary", size = "md", asChild = false, ...props }, ref) => {
39
+ const Comp = asChild ? Slot : "button";
40
+ return /* @__PURE__ */ jsx(
41
+ Comp,
42
+ {
43
+ ref,
44
+ className: buttonVariants({ variant, size, className }),
45
+ ...props
46
+ }
47
+ );
48
+ }
49
+ );
50
+ Button.displayName = "Button";
51
+
52
+ export { Button, buttonVariants };
53
+ //# sourceMappingURL=chunk-ADE22JSR.js.map
54
+ //# sourceMappingURL=chunk-ADE22JSR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Button.tsx"],"names":[],"mappings":";;;;;AAIA,IAAM,QAAA,GAAW;AAAA,EACf,OAAA,EAAS,mHAAA;AAAA,EACT,SAAA,EAAW,uIAAA;AAAA,EACX,KAAA,EAAO,iIAAA;AAAA,EACP,WAAA,EAAa,gGAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAGA,IAAM,aAAA,GAAgB;AAAA,EACpB,OAAA,EAAS,uBAAA;AAAA,EACT,SAAA,EAAW,EAAA;AAAA,EACX,KAAA,EAAO,EAAA;AAAA,EACP,WAAA,EAAa,EAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAEA,IAAM,KAAA,GAAQ;AAAA,EACZ,EAAA,EAAI,mBAAA;AAAA,EACJ,EAAA,EAAI,qBAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAOO,SAAS,cAAA,CAAe,EAAE,OAAA,GAAU,WAAA,EAAa,OAAO,IAAA,EAAM,SAAA,EAAU,GAAiD,EAAC,EAAG;AAClI,EAAA,OAAO,EAAA;AAAA,IACL,+MAAA;AAAA,IACA,uBAAA;AAAA,IACA,kDAAA;AAAA,IACA,SAAS,OAAO,CAAA;AAAA,IAChB,cAAc,OAAO,CAAA;AAAA,IACrB,MAAM,IAAI,CAAA;AAAA,IACV;AAAA,GACF;AACF;AAOA,IAAM,MAAA,GAAS,UAAA;AAAA,EACb,CAAC,EAAE,SAAA,EAAW,OAAA,GAAU,WAAA,EAAa,IAAA,GAAO,IAAA,EAAM,OAAA,GAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACrF,IAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,IAAA,uBACE,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,WAAW,cAAA,CAAe,EAAE,OAAA,EAAS,IAAA,EAAM,WAAW,CAAA;AAAA,QACrD,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-ADE22JSR.js","sourcesContent":["import { type ButtonHTMLAttributes, forwardRef } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { cn } from '@/lib/utils'\n\nconst variants = {\n primary: 'bg-tollerud-yellow text-tollerud-black border-tollerud-yellow hover:bg-tollerud-yellow hover:shadow-tollerud-glow',\n secondary: 'bg-transparent text-tollerud-text-primary border-tollerud-border hover:border-tollerud-text-secondary hover:bg-tollerud-surface-hover',\n ghost: 'bg-transparent text-tollerud-text-secondary border-transparent hover:text-tollerud-text-primary hover:bg-tollerud-surface-hover',\n destructive: 'bg-tollerud-error text-white border-tollerud-error hover:shadow-[0_0_12px_rgba(239,68,68,0.3)]',\n terminal: 'font-mono text-tollerud-yellow border-[rgba(255,255,0,0.25)] bg-transparent hover:border-tollerud-yellow hover:shadow-tollerud-glow hover:bg-[rgba(255,255,0,0.05)]',\n} as const\n\n/** Layer classes from globals-layers.css — ❯ prefix, hover glow, magnetic glow in docs */\nconst variantLayers = {\n primary: 'tollerud-btn--primary',\n secondary: '',\n ghost: '',\n destructive: '',\n terminal: 'tollerud-btn--terminal',\n} as const\n\nconst sizes = {\n sm: 'px-3 py-1 text-sm',\n md: 'px-4 py-2 text-base',\n lg: 'px-6 py-3 text-lg',\n} as const\n\nexport interface ButtonVariantProps {\n variant?: keyof typeof variants\n size?: keyof typeof sizes\n}\n\nexport function buttonVariants({ variant = 'secondary', size = 'md', className }: ButtonVariantProps & { className?: string } = {}) {\n return cn(\n 'tollerud-btn inline-flex items-center justify-center gap-2 font-semibold rounded transition-all duration-[150ms] focus-visible:outline-2 focus-visible:outline-tollerud-yellow focus-visible:outline-offset-2',\n 'border cursor-pointer',\n 'disabled:opacity-50 disabled:pointer-events-none',\n variants[variant],\n variantLayers[variant],\n sizes[size],\n className\n )\n}\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, ButtonVariantProps {\n /** Render as the single child element (e.g. a `<Link>`) instead of a `<button>`, merging props and styles onto it. */\n asChild?: boolean\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'secondary', size = 'md', asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button'\n return (\n <Comp\n ref={ref}\n className={buttonVariants({ variant, size, className })}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\nexport { Button }\n"]}
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var toneStyles = {
7
+ default: { wrapper: "border-tollerud-border bg-tollerud-surface-raised", icon: "text-tollerud-text-muted" },
8
+ accent: { wrapper: "border-tollerud-yellow/30 bg-tollerud-yellow/5", icon: "text-tollerud-yellow" },
9
+ info: { wrapper: "border-blue-500/30 bg-blue-500/5", icon: "text-blue-400" },
10
+ success: { wrapper: "border-green-500/30 bg-green-500/5", icon: "text-green-400" },
11
+ error: { wrapper: "border-red-500/30 bg-red-500/5", icon: "text-red-400" }
12
+ };
13
+ var Alert = forwardRef(
14
+ ({ className, tone = "default", title, icon, children, ...props }, ref) => {
15
+ const styles = toneStyles[tone];
16
+ return /* @__PURE__ */ jsxs(
17
+ "div",
18
+ {
19
+ ref,
20
+ role: "alert",
21
+ className: cn(
22
+ "flex gap-3 rounded-md border p-4",
23
+ styles.wrapper,
24
+ className
25
+ ),
26
+ ...props,
27
+ children: [
28
+ icon && /* @__PURE__ */ jsx("span", { className: cn("mt-0.5 flex-shrink-0 w-[18px] h-[18px]", styles.icon), children: icon }),
29
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
30
+ title && /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-tollerud-text-primary leading-snug", children: title }),
31
+ children && /* @__PURE__ */ jsx("p", { className: cn("text-sm text-tollerud-text-secondary leading-relaxed", title && "mt-1"), children })
32
+ ] })
33
+ ]
34
+ }
35
+ );
36
+ }
37
+ );
38
+ Alert.displayName = "Alert";
39
+
40
+ export { Alert };
41
+ //# sourceMappingURL=chunk-ANW6J6PV.js.map
42
+ //# sourceMappingURL=chunk-ANW6J6PV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Alert.tsx"],"names":[],"mappings":";;;;AAGA,IAAM,UAAA,GAAa;AAAA,EACjB,OAAA,EAAS,EAAE,OAAA,EAAS,mDAAA,EAAqD,MAAM,0BAAA,EAA2B;AAAA,EAC1G,MAAA,EAAS,EAAE,OAAA,EAAS,gDAAA,EAAqD,MAAM,sBAAA,EAAuB;AAAA,EACtG,IAAA,EAAS,EAAE,OAAA,EAAS,kCAAA,EAAqD,MAAM,eAAA,EAAgB;AAAA,EAC/F,OAAA,EAAS,EAAE,OAAA,EAAS,oCAAA,EAAqD,MAAM,gBAAA,EAAiB;AAAA,EAChG,KAAA,EAAS,EAAE,OAAA,EAAS,gCAAA,EAAqD,MAAM,cAAA;AACjF,CAAA;AAQA,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,IAAA,GAAO,SAAA,EAAW,KAAA,EAAO,IAAA,EAAM,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACzE,IAAA,MAAM,MAAA,GAAS,WAAW,IAAI,CAAA;AAC9B,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,EAAW,EAAA;AAAA,UACT,kCAAA;AAAA,UACA,MAAA,CAAO,OAAA;AAAA,UACP;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,IAAA,oBACC,GAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,0CAA0C,MAAA,CAAO,IAAI,GACtE,QAAA,EAAA,IAAA,EACH,CAAA;AAAA,0BAEF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EACZ,QAAA,EAAA;AAAA,YAAA,KAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+DAAA,EACV,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,YAED,QAAA,wBACE,GAAA,EAAA,EAAE,SAAA,EAAW,GAAG,sDAAA,EAAwD,KAAA,IAAS,MAAM,CAAA,EACrF,QAAA,EACH;AAAA,WAAA,EAEJ;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-ANW6J6PV.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nconst toneStyles = {\n default: { wrapper: 'border-tollerud-border bg-tollerud-surface-raised', icon: 'text-tollerud-text-muted' },\n accent: { wrapper: 'border-tollerud-yellow/30 bg-tollerud-yellow/5', icon: 'text-tollerud-yellow' },\n info: { wrapper: 'border-blue-500/30 bg-blue-500/5', icon: 'text-blue-400' },\n success: { wrapper: 'border-green-500/30 bg-green-500/5', icon: 'text-green-400' },\n error: { wrapper: 'border-red-500/30 bg-red-500/5', icon: 'text-red-400' },\n} as const\n\nexport interface AlertProps extends HTMLAttributes<HTMLDivElement> {\n tone?: keyof typeof toneStyles\n title?: string\n icon?: React.ReactNode\n}\n\nconst Alert = forwardRef<HTMLDivElement, AlertProps>(\n ({ className, tone = 'default', title, icon, children, ...props }, ref) => {\n const styles = toneStyles[tone]\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(\n 'flex gap-3 rounded-md border p-4',\n styles.wrapper,\n className\n )}\n {...props}\n >\n {icon && (\n <span className={cn('mt-0.5 flex-shrink-0 w-[18px] h-[18px]', styles.icon)}>\n {icon}\n </span>\n )}\n <div className=\"min-w-0\">\n {title && (\n <p className=\"text-sm font-semibold text-tollerud-text-primary leading-snug\">\n {title}\n </p>\n )}\n {children && (\n <p className={cn('text-sm text-tollerud-text-secondary leading-relaxed', title && 'mt-1')}>\n {children}\n </p>\n )}\n </div>\n </div>\n )\n }\n)\nAlert.displayName = 'Alert'\n\nexport { Alert }\n"]}
@@ -0,0 +1,80 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var stateStyles = {
7
+ pending: "border-tollerud-yellow/30 hover:border-tollerud-yellow/50",
8
+ approved: "border-tollerud-success/40 opacity-70",
9
+ rejected: "border-tollerud-error/40 opacity-70"
10
+ };
11
+ var stateLabels = {
12
+ pending: { text: "Awaiting approval", cls: "text-tollerud-yellow" },
13
+ approved: { text: "Approved", cls: "text-tollerud-success" },
14
+ rejected: { text: "Rejected", cls: "text-tollerud-error" }
15
+ };
16
+ var ApprovalCard = forwardRef(
17
+ ({ className, action, description, source, state = "pending", timestamp, onApprove, onReject, disabled, loading, ...props }, ref) => {
18
+ const label = stateLabels[state];
19
+ return /* @__PURE__ */ jsxs(
20
+ "div",
21
+ {
22
+ ref,
23
+ className: cn(
24
+ "rounded-lg border bg-tollerud-surface-raised p-4",
25
+ "transition-all duration-[150ms]",
26
+ stateStyles[state],
27
+ loading && "animate-pulse",
28
+ className
29
+ ),
30
+ ...props,
31
+ children: [
32
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
33
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-tollerud-foreground truncate", children: action }),
34
+ /* @__PURE__ */ jsx("span", { className: cn("text-[11px] font-medium whitespace-nowrap ml-2", label.cls), children: label.text })
35
+ ] }),
36
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-text-secondary mb-1.5 leading-relaxed", children: description }),
37
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-x-4 gap-y-0.5 text-[11px] text-tollerud-text-muted mb-3", children: [
38
+ source && /* @__PURE__ */ jsx("span", { className: "font-mono", children: source }),
39
+ timestamp && /* @__PURE__ */ jsx("span", { children: timestamp })
40
+ ] }),
41
+ state === "pending" && /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
42
+ /* @__PURE__ */ jsx(
43
+ "button",
44
+ {
45
+ type: "button",
46
+ disabled,
47
+ onClick: onApprove,
48
+ className: cn(
49
+ "flex-1 rounded-md px-3 py-1.5 text-xs font-semibold transition-all",
50
+ "bg-tollerud-success text-tollerud-text-inverse",
51
+ "hover:brightness-110 disabled:opacity-40 disabled:cursor-not-allowed"
52
+ ),
53
+ children: "Approve"
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsx(
57
+ "button",
58
+ {
59
+ type: "button",
60
+ disabled,
61
+ onClick: onReject,
62
+ className: cn(
63
+ "flex-1 rounded-md px-3 py-1.5 text-xs font-semibold transition-all",
64
+ "bg-tollerud-error text-white",
65
+ "hover:brightness-110 disabled:opacity-40 disabled:cursor-not-allowed"
66
+ ),
67
+ children: "Reject"
68
+ }
69
+ )
70
+ ] })
71
+ ]
72
+ }
73
+ );
74
+ }
75
+ );
76
+ ApprovalCard.displayName = "ApprovalCard";
77
+
78
+ export { ApprovalCard };
79
+ //# sourceMappingURL=chunk-APFFKNPS.js.map
80
+ //# sourceMappingURL=chunk-APFFKNPS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/ApprovalCard.tsx"],"names":[],"mappings":";;;;AA0BA,IAAM,WAAA,GAA6C;AAAA,EACjD,OAAA,EAAU,2DAAA;AAAA,EACV,QAAA,EAAU,uCAAA;AAAA,EACV,QAAA,EAAU;AACZ,CAAA;AAEA,IAAM,WAAA,GAAoE;AAAA,EACxE,OAAA,EAAU,EAAE,IAAA,EAAM,mBAAA,EAAqB,KAAK,sBAAA,EAAuB;AAAA,EACnE,QAAA,EAAU,EAAE,IAAA,EAAM,UAAA,EAAY,KAAK,uBAAA,EAAwB;AAAA,EAC3D,QAAA,EAAU,EAAE,IAAA,EAAM,UAAA,EAAY,KAAK,qBAAA;AACrC,CAAA;AAEA,IAAM,YAAA,GAAe,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,MAAA,EAAQ,WAAA,EAAa,QAAQ,KAAA,GAAQ,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,UAAU,QAAA,EAAU,OAAA,EAAS,GAAG,KAAA,IAAS,GAAA,KAAQ;AACnI,IAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAE/B,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,kDAAA;AAAA,UACA,iCAAA;AAAA,UACA,YAAY,KAAK,CAAA;AAAA,UACjB,OAAA,IAAW,eAAA;AAAA,UACX;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0CAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yDAAA,EAA2D,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,4BAClF,GAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,kDAAkD,KAAA,CAAM,GAAG,CAAA,EAAI,QAAA,EAAA,KAAA,CAAM,IAAA,EAAK;AAAA,WAAA,EAChG,CAAA;AAAA,UACC,WAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+DAA+D,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,0BAE1F,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4EAAA,EACZ,QAAA,EAAA;AAAA,YAAA,MAAA,oBAAU,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAa,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,YAC9C,SAAA,oBAAa,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,SAAA,EAAU;AAAA,WAAA,EACjC,CAAA;AAAA,UACC,KAAA,KAAU,SAAA,oBACT,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,YAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,QAAA;AAAA,gBACA,OAAA,EAAS,SAAA;AAAA,gBACT,SAAA,EAAW,EAAA;AAAA,kBACT,oEAAA;AAAA,kBACA,gDAAA;AAAA,kBACA;AAAA,iBACF;AAAA,gBACD,QAAA,EAAA;AAAA;AAAA,aAED;AAAA,4BACA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,QAAA;AAAA,gBACA,OAAA,EAAS,QAAA;AAAA,gBACT,SAAA,EAAW,EAAA;AAAA,kBACT,oEAAA;AAAA,kBACA,8BAAA;AAAA,kBACA;AAAA,iBACF;AAAA,gBACD,QAAA,EAAA;AAAA;AAAA;AAED,WAAA,EACF;AAAA;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AACA,YAAA,CAAa,WAAA,GAAc,cAAA","file":"chunk-APFFKNPS.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport type ApprovalState = 'pending' | 'approved' | 'rejected'\n\nexport interface ApprovalCardProps extends HTMLAttributes<HTMLDivElement> {\n /** Action being approved */\n action: string\n /** Description of what will happen */\n description?: string\n /** Source (e.g. 'Emma → backup.sh') */\n source?: string\n /** Current approval state */\n state?: ApprovalState\n /** Timestamp of the request */\n timestamp?: string\n /** Called when user approves */\n onApprove?: () => void\n /** Called when user rejects */\n onReject?: () => void\n /** Whether actions are disabled */\n disabled?: boolean\n /** Whether the card is loading */\n loading?: boolean\n}\n\nconst stateStyles: Record<ApprovalState, string> = {\n pending: 'border-tollerud-yellow/30 hover:border-tollerud-yellow/50',\n approved: 'border-tollerud-success/40 opacity-70',\n rejected: 'border-tollerud-error/40 opacity-70',\n}\n\nconst stateLabels: Record<ApprovalState, { text: string; cls: string }> = {\n pending: { text: 'Awaiting approval', cls: 'text-tollerud-yellow' },\n approved: { text: 'Approved', cls: 'text-tollerud-success' },\n rejected: { text: 'Rejected', cls: 'text-tollerud-error' },\n}\n\nconst ApprovalCard = forwardRef<HTMLDivElement, ApprovalCardProps>(\n ({ className, action, description, source, state = 'pending', timestamp, onApprove, onReject, disabled, loading, ...props }, ref) => {\n const label = stateLabels[state]\n\n return (\n <div\n ref={ref}\n className={cn(\n 'rounded-lg border bg-tollerud-surface-raised p-4',\n 'transition-all duration-[150ms]',\n stateStyles[state],\n loading && 'animate-pulse',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between mb-1.5\">\n <span className=\"text-sm font-semibold text-tollerud-foreground truncate\">{action}</span>\n <span className={cn('text-[11px] font-medium whitespace-nowrap ml-2', label.cls)}>{label.text}</span>\n </div>\n {description && (\n <p className=\"text-xs text-tollerud-text-secondary mb-1.5 leading-relaxed\">{description}</p>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-0.5 text-[11px] text-tollerud-text-muted mb-3\">\n {source && <span className=\"font-mono\">{source}</span>}\n {timestamp && <span>{timestamp}</span>}\n </div>\n {state === 'pending' && (\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onApprove}\n className={cn(\n 'flex-1 rounded-md px-3 py-1.5 text-xs font-semibold transition-all',\n 'bg-tollerud-success text-tollerud-text-inverse',\n 'hover:brightness-110 disabled:opacity-40 disabled:cursor-not-allowed'\n )}\n >\n Approve\n </button>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onReject}\n className={cn(\n 'flex-1 rounded-md px-3 py-1.5 text-xs font-semibold transition-all',\n 'bg-tollerud-error text-white',\n 'hover:brightness-110 disabled:opacity-40 disabled:cursor-not-allowed'\n )}\n >\n Reject\n </button>\n </div>\n )}\n </div>\n )\n }\n)\nApprovalCard.displayName = 'ApprovalCard'\n\nexport { ApprovalCard }\n"]}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ function Skeleton({ className, h, w, r, style, ...props }) {
6
+ return /* @__PURE__ */ jsx(
7
+ "div",
8
+ {
9
+ className: cn("tollerud-skeleton", className),
10
+ style: {
11
+ ...h != null ? { height: h } : null,
12
+ ...w != null ? { width: w } : null,
13
+ ...r != null ? { borderRadius: r } : null,
14
+ ...style
15
+ },
16
+ ...props
17
+ }
18
+ );
19
+ }
20
+
21
+ export { Skeleton };
22
+ //# sourceMappingURL=chunk-AQT3FZRQ.js.map
23
+ //# sourceMappingURL=chunk-AQT3FZRQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Skeleton.tsx"],"names":[],"mappings":";;;AAWA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,CAAA,EAAG,GAAG,CAAA,EAAG,KAAA,EAAO,GAAG,KAAA,EAAM,EAAkB;AACxE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA;AAAA,MAC5C,KAAA,EAAO;AAAA,QACL,GAAI,CAAA,IAAK,IAAA,GAAO,EAAE,MAAA,EAAQ,GAAE,GAAI,IAAA;AAAA,QAChC,GAAI,CAAA,IAAK,IAAA,GAAO,EAAE,KAAA,EAAO,GAAE,GAAI,IAAA;AAAA,QAC/B,GAAI,CAAA,IAAK,IAAA,GAAO,EAAE,YAAA,EAAc,GAAE,GAAI,IAAA;AAAA,QACtC,GAAG;AAAA,OACL;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-AQT3FZRQ.js","sourcesContent":["import { cn } from '@/lib/utils'\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Shorthand height in px (or any CSS length via className) */\n h?: number | string\n /** Shorthand width in px or percentage string e.g. \"60%\" */\n w?: number | string\n /** Shorthand border-radius in px */\n r?: number | string\n}\n\nfunction Skeleton({ className, h, w, r, style, ...props }: SkeletonProps) {\n return (\n <div\n className={cn('tollerud-skeleton', className)}\n style={{\n ...(h != null ? { height: h } : null),\n ...(w != null ? { width: w } : null),\n ...(r != null ? { borderRadius: r } : null),\n ...style,\n }}\n {...props}\n />\n )\n}\n\nexport { Skeleton }\n"]}