@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,85 @@
1
+ 'use client';
2
+ import { IncidentCard } from './chunk-EN4OJCEF.js';
3
+ import { cn } from './chunk-WSQNPRGN.js';
4
+ import { forwardRef } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var AlertInbox = forwardRef(
8
+ ({ className, alerts, filterSeverity = "", onAcknowledge, loading, emptyMessage = "All clear \u2014 no incidents", ...props }, ref) => {
9
+ const filtered = filterSeverity ? alerts.filter((a) => a.severity === filterSeverity) : alerts;
10
+ const counts = {
11
+ total: alerts.length,
12
+ unacknowledged: alerts.filter((a) => !a.acknowledged).length,
13
+ critical: alerts.filter((a) => a.severity === "critical" && !a.acknowledged).length
14
+ };
15
+ return /* @__PURE__ */ jsxs(
16
+ "div",
17
+ {
18
+ ref,
19
+ className: cn(
20
+ "rounded-lg border border-tollerud-border bg-tollerud-surface-raised overflow-hidden",
21
+ loading && "animate-pulse",
22
+ className
23
+ ),
24
+ ...props,
25
+ children: [
26
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-tollerud-border", children: [
27
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
28
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-tollerud-foreground", children: "Alerts" }),
29
+ counts.unacknowledged > 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-[11px] text-tollerud-error font-medium", children: [
30
+ /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-tollerud-error animate-pulse" }),
31
+ counts.unacknowledged,
32
+ " unread"
33
+ ] }),
34
+ counts.critical > 0 && /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-tollerud-error font-bold", children: [
35
+ counts.critical,
36
+ " critical"
37
+ ] })
38
+ ] }),
39
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-tollerud-text-muted", children: [
40
+ filtered.length,
41
+ " of ",
42
+ alerts.length
43
+ ] })
44
+ ] }),
45
+ /* @__PURE__ */ jsxs("div", { className: "divide-y divide-tollerud-border/50 max-h-[480px] overflow-y-auto", children: [
46
+ filtered.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-xs text-center text-tollerud-text-muted", children: emptyMessage }),
47
+ filtered.map((alert) => /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
48
+ /* @__PURE__ */ jsx(
49
+ IncidentCard,
50
+ {
51
+ title: alert.title,
52
+ severity: alert.severity,
53
+ timestamp: alert.timestamp,
54
+ description: alert.description,
55
+ service: alert.service,
56
+ acknowledged: alert.acknowledged,
57
+ className: "border-0 rounded-none bg-transparent hover:bg-tollerud-noir-800/30"
58
+ }
59
+ ),
60
+ alert.acknowledged && /* @__PURE__ */ jsx("span", { className: "absolute bottom-2 right-3 text-[10px] font-medium text-tollerud-text-muted/50", children: "Acknowledged" }),
61
+ !alert.acknowledged && onAcknowledge && /* @__PURE__ */ jsx(
62
+ "button",
63
+ {
64
+ type: "button",
65
+ onClick: () => onAcknowledge(alert.id),
66
+ className: cn(
67
+ "absolute bottom-2 right-3 text-[10px] font-medium px-2 py-0.5 rounded",
68
+ "text-tollerud-yellow/70 hover:text-tollerud-yellow hover:bg-tollerud-yellow/10",
69
+ "opacity-0 group-hover:opacity-100 transition-opacity duration-150"
70
+ ),
71
+ children: "Acknowledge"
72
+ }
73
+ )
74
+ ] }, alert.id))
75
+ ] })
76
+ ]
77
+ }
78
+ );
79
+ }
80
+ );
81
+ AlertInbox.displayName = "AlertInbox";
82
+
83
+ export { AlertInbox };
84
+ //# sourceMappingURL=chunk-AZADSX4Z.js.map
85
+ //# sourceMappingURL=chunk-AZADSX4Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/AlertInbox.tsx"],"names":[],"mappings":";;;;;AAwBA,IAAM,UAAA,GAAa,UAAA;AAAA,EACjB,CAAC,EAAE,SAAA,EAAW,MAAA,EAAQ,cAAA,GAAiB,EAAA,EAAI,aAAA,EAAe,OAAA,EAAS,YAAA,GAAe,+BAAA,EAA4B,GAAG,KAAA,IAAS,GAAA,KAAQ;AAChI,IAAA,MAAM,QAAA,GAAW,iBACb,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,KAAa,cAAc,CAAA,GAClD,MAAA;AAEJ,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,OAAO,MAAA,CAAO,MAAA;AAAA,MACd,cAAA,EAAgB,OAAO,MAAA,CAAO,CAAC,MAAM,CAAC,CAAA,CAAE,YAAY,CAAA,CAAE,MAAA;AAAA,MACtD,QAAA,EAAU,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,KAAa,UAAA,IAAc,CAAC,CAAA,CAAE,YAAY,CAAA,CAAE;AAAA,KAC/E;AAEA,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,qFAAA;AAAA,UACA,OAAA,IAAW,eAAA;AAAA,UACX;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAGJ,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,6EAAA,EACb,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EACb,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gDAAA,EAAiD,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,cACtE,OAAO,cAAA,GAAiB,CAAA,oBACvB,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,4EAAA,EACd,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,0DAAA,EAA2D,CAAA;AAAA,gBAC1E,MAAA,CAAO,cAAA;AAAA,gBAAe;AAAA,eAAA,EACzB,CAAA;AAAA,cAED,OAAO,QAAA,GAAW,CAAA,oBACjB,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2CAAA,EAA6C,QAAA,EAAA;AAAA,gBAAA,MAAA,CAAO,QAAA;AAAA,gBAAS;AAAA,eAAA,EAAS;AAAA,aAAA,EAE1F,CAAA;AAAA,4BACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAA,EAAoC,QAAA,EAAA;AAAA,cAAA,QAAA,CAAS,MAAA;AAAA,cAAO,MAAA;AAAA,cAAK,MAAA,CAAO;AAAA,aAAA,EAAO;AAAA,WAAA,EACzF,CAAA;AAAA,0BAGA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kEAAA,EACZ,QAAA,EAAA;AAAA,YAAA,QAAA,CAAS,WAAW,CAAA,oBACnB,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0DAA0D,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,YAEvF,SAAS,GAAA,CAAI,CAAC,0BACb,IAAA,CAAC,KAAA,EAAA,EAAmB,WAAU,gBAAA,EAC5B,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,YAAA;AAAA,gBAAA;AAAA,kBACC,OAAO,KAAA,CAAM,KAAA;AAAA,kBACb,UAAU,KAAA,CAAM,QAAA;AAAA,kBAChB,WAAW,KAAA,CAAM,SAAA;AAAA,kBACjB,aAAa,KAAA,CAAM,WAAA;AAAA,kBACnB,SAAS,KAAA,CAAM,OAAA;AAAA,kBACf,cAAc,KAAA,CAAM,YAAA;AAAA,kBACpB,SAAA,EAAU;AAAA;AAAA,eACZ;AAAA,cAEC,MAAM,YAAA,oBACL,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iFAAgF,QAAA,EAAA,cAAA,EAEhG,CAAA;AAAA,cAGD,CAAC,KAAA,CAAM,YAAA,IAAgB,aAAA,oBACtB,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,QAAA;AAAA,kBACL,OAAA,EAAS,MAAM,aAAA,CAAc,KAAA,CAAM,EAAE,CAAA;AAAA,kBACrC,SAAA,EAAW,EAAA;AAAA,oBACT,uEAAA;AAAA,oBACA,gFAAA;AAAA,oBACA;AAAA,mBACF;AAAA,kBACD,QAAA,EAAA;AAAA;AAAA;AAED,aAAA,EAAA,EA5BM,KAAA,CAAM,EA8BhB,CACD;AAAA,WAAA,EACH;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,UAAA,CAAW,WAAA,GAAc,YAAA","file":"chunk-AZADSX4Z.js","sourcesContent":["'use client'\n\nimport { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\nimport { IncidentCard, type IncidentSeverity } from './IncidentCard'\n\nexport interface AlertItem {\n id: string\n title: string\n severity: IncidentSeverity\n timestamp: string\n description?: string\n service?: string\n acknowledged?: boolean\n}\n\nexport interface AlertInboxProps extends HTMLAttributes<HTMLDivElement> {\n alerts: AlertItem[]\n filterSeverity?: IncidentSeverity | ''\n onAcknowledge?: (id: string) => void\n loading?: boolean\n emptyMessage?: string\n}\n\nconst AlertInbox = forwardRef<HTMLDivElement, AlertInboxProps>(\n ({ className, alerts, filterSeverity = '', onAcknowledge, loading, emptyMessage = 'All clear — no incidents', ...props }, ref) => {\n const filtered = filterSeverity\n ? alerts.filter((a) => a.severity === filterSeverity)\n : alerts\n\n const counts = {\n total: alerts.length,\n unacknowledged: alerts.filter((a) => !a.acknowledged).length,\n critical: alerts.filter((a) => a.severity === 'critical' && !a.acknowledged).length,\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n 'rounded-lg border border-tollerud-border bg-tollerud-surface-raised overflow-hidden',\n loading && 'animate-pulse',\n className\n )}\n {...props}\n >\n {/* Header bar */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-tollerud-border\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-tollerud-foreground\">Alerts</span>\n {counts.unacknowledged > 0 && (\n <span className=\"inline-flex items-center gap-1 text-[11px] text-tollerud-error font-medium\">\n <span className=\"w-1.5 h-1.5 rounded-full bg-tollerud-error animate-pulse\" />\n {counts.unacknowledged} unread\n </span>\n )}\n {counts.critical > 0 && (\n <span className=\"text-[11px] text-tollerud-error font-bold\">{counts.critical} critical</span>\n )}\n </div>\n <span className=\"text-xs text-tollerud-text-muted\">{filtered.length} of {alerts.length}</span>\n </div>\n\n {/* Alert list */}\n <div className=\"divide-y divide-tollerud-border/50 max-h-[480px] overflow-y-auto\">\n {filtered.length === 0 && (\n <div className=\"px-4 py-8 text-xs text-center text-tollerud-text-muted\">{emptyMessage}</div>\n )}\n {filtered.map((alert) => (\n <div key={alert.id} className=\"relative group\">\n <IncidentCard\n title={alert.title}\n severity={alert.severity}\n timestamp={alert.timestamp}\n description={alert.description}\n service={alert.service}\n acknowledged={alert.acknowledged}\n className=\"border-0 rounded-none bg-transparent hover:bg-tollerud-noir-800/30\"\n />\n {/* Acknowledged indicator */}\n {alert.acknowledged && (\n <span className=\"absolute bottom-2 right-3 text-[10px] font-medium text-tollerud-text-muted/50\">\n Acknowledged\n </span>\n )}\n {/* Acknowledge button */}\n {!alert.acknowledged && onAcknowledge && (\n <button\n type=\"button\"\n onClick={() => onAcknowledge(alert.id)}\n className={cn(\n 'absolute bottom-2 right-3 text-[10px] font-medium px-2 py-0.5 rounded',\n 'text-tollerud-yellow/70 hover:text-tollerud-yellow hover:bg-tollerud-yellow/10',\n 'opacity-0 group-hover:opacity-100 transition-opacity duration-150'\n )}\n >\n Acknowledge\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n )\n }\n)\nAlertInbox.displayName = 'AlertInbox'\n\nexport { AlertInbox }"]}
@@ -0,0 +1,36 @@
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 Input = forwardRef(
7
+ ({ className, label, error, id, ...props }, ref) => {
8
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
9
+ label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "text-xs font-medium text-tollerud-text-muted", children: label }),
10
+ /* @__PURE__ */ jsx(
11
+ "input",
12
+ {
13
+ ref,
14
+ id,
15
+ className: cn(
16
+ "font-sans text-base px-3 py-2 rounded",
17
+ "bg-tollerud-surface-raised border",
18
+ "text-tollerud-text-primary",
19
+ "placeholder:text-tollerud-text-muted",
20
+ "transition-[border-color] duration-[150ms]",
21
+ "focus:outline-none focus:border-tollerud-yellow focus:shadow-[0_0_0_1px_#E8D500]",
22
+ error ? "border-tollerud-error" : "border-tollerud-border",
23
+ className
24
+ ),
25
+ ...props
26
+ }
27
+ ),
28
+ error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error mt-0.5", children: error })
29
+ ] });
30
+ }
31
+ );
32
+ Input.displayName = "Input";
33
+
34
+ export { Input };
35
+ //# sourceMappingURL=chunk-BPCH5LJ3.js.map
36
+ //# sourceMappingURL=chunk-BPCH5LJ3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Input.tsx"],"names":[],"mappings":";;;;AAQA,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,OAAO,EAAA,EAAI,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAClD,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACZ,QAAA,EAAA;AAAA,MAAA,KAAA,wBACE,OAAA,EAAA,EAAM,OAAA,EAAS,EAAA,EAAI,SAAA,EAAU,gDAC3B,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,sBAEF,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,EAAA;AAAA,UACA,SAAA,EAAW,EAAA;AAAA,YACT,uCAAA;AAAA,YACA,mCAAA;AAAA,YACA,4BAAA;AAAA,YACA,sCAAA;AAAA,YACA,4CAAA;AAAA,YACA,kFAAA;AAAA,YACA,QAAQ,uBAAA,GAA0B,wBAAA;AAAA,YAClC;AAAA,WACF;AAAA,UACC,GAAG;AAAA;AAAA,OACN;AAAA,MACC,KAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCAAsC,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EAE7D,CAAA;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-BPCH5LJ3.js","sourcesContent":["import { type InputHTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface InputProps extends InputHTMLAttributes<HTMLInputElement> {\n label?: string\n error?: string\n}\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n ({ className, label, error, id, ...props }, ref) => {\n return (\n <div className=\"flex flex-col gap-1\">\n {label && (\n <label htmlFor={id} className=\"text-xs font-medium text-tollerud-text-muted\">\n {label}\n </label>\n )}\n <input\n ref={ref}\n id={id}\n className={cn(\n 'font-sans text-base px-3 py-2 rounded',\n 'bg-tollerud-surface-raised border',\n 'text-tollerud-text-primary',\n 'placeholder:text-tollerud-text-muted',\n 'transition-[border-color] duration-[150ms]',\n 'focus:outline-none focus:border-tollerud-yellow focus:shadow-[0_0_0_1px_#E8D500]',\n error ? 'border-tollerud-error' : 'border-tollerud-border',\n className\n )}\n {...props}\n />\n {error && (\n <p className=\"text-xs text-tollerud-error mt-0.5\">{error}</p>\n )}\n </div>\n )\n }\n)\nInput.displayName = 'Input'\n\nexport { Input }\n"]}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { Toaster as Toaster$1 } from 'sonner';
3
+ import { useState, useEffect } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ // components/Toaster.tsx
7
+ var Toaster = ({ theme = "dark", ...props }) => {
8
+ const [mobile, setMobile] = useState(false);
9
+ useEffect(() => {
10
+ const check = () => setMobile(window.innerWidth < 640);
11
+ check();
12
+ window.addEventListener("resize", check);
13
+ return () => window.removeEventListener("resize", check);
14
+ }, []);
15
+ return /* @__PURE__ */ jsx(
16
+ Toaster$1,
17
+ {
18
+ position: mobile ? "top-center" : "top-right",
19
+ theme,
20
+ className: "toaster group",
21
+ toastOptions: {
22
+ classNames: {
23
+ toast: "group toast group-[.toaster]:bg-tollerud-noir-900 group-[.toaster]:text-tollerud-foreground group-[.toaster]:border group-[.toaster]:border-tollerud-border/30 group-[.toaster]:shadow-lg",
24
+ description: "group-[.toast]:text-tollerud-text-muted text-xs",
25
+ actionButton: "group-[.toast]:bg-tollerud-yellow group-[.toast]:text-tollerud-black group-[.toast]:text-xs group-[.toast]:font-medium group-[.toast]:px-3 group-[.toast]:py-1 group-[.toast]:rounded",
26
+ cancelButton: "group-[.toast]:bg-tollerud-noir-800 group-[.toast]:text-tollerud-text-muted group-[.toast]:text-xs group-[.toast]:px-3 group-[.toast]:py-1 group-[.toast]:rounded",
27
+ success: "group-[.toast]:border-l-tollerud-success group-[.toast]:border-l-2",
28
+ error: "group-[.toast]:border-l-tollerud-error group-[.toast]:border-l-2",
29
+ warning: "group-[.toast]:border-l-tollerud-yellow group-[.toast]:border-l-2",
30
+ info: "group-[.toast]:border-l-tollerud-info group-[.toast]:border-l-2"
31
+ }
32
+ },
33
+ ...props
34
+ }
35
+ );
36
+ };
37
+
38
+ export { Toaster };
39
+ //# sourceMappingURL=chunk-CDI7353B.js.map
40
+ //# sourceMappingURL=chunk-CDI7353B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Toaster.tsx"],"names":["SonnerToaster"],"mappings":";;;;;AAUA,IAAM,UAAU,CAAC,EAAE,QAAQ,MAAA,EAAQ,GAAG,OAAM,KAA4B;AACtE,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAE1C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,CAAU,MAAA,CAAO,aAAa,GAAG,CAAA;AACrD,IAAA,KAAA,EAAM;AACN,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,KAAK,CAAA;AACvC,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,KAAK,CAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,uBACE,GAAA;AAAA,IAACA,SAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAU,SAAS,YAAA,GAAe,WAAA;AAAA,MAClC,KAAA;AAAA,MACA,SAAA,EAAU,eAAA;AAAA,MACV,YAAA,EAAc;AAAA,QACZ,UAAA,EAAY;AAAA,UACV,KAAA,EACE,2LAAA;AAAA,UAGF,WAAA,EAAa,iDAAA;AAAA,UACb,YAAA,EACE,uLAAA;AAAA,UAEF,YAAA,EACE,mKAAA;AAAA,UAEF,OAAA,EAAS,oEAAA;AAAA,UACT,KAAA,EAAO,kEAAA;AAAA,UACP,OAAA,EAAS,mEAAA;AAAA,UACT,IAAA,EAAM;AAAA;AACR,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-CDI7353B.js","sourcesContent":["'use client'\n\nimport { Toaster as SonnerToaster, type ToasterProps } from 'sonner'\nimport { useEffect, useState } from 'react'\n\nexport type TollerudToasterProps = ToasterProps & {\n /** Toast color theme. Wire to your app theme when you have one. */\n theme?: ToasterProps['theme']\n}\n\nconst Toaster = ({ theme = 'dark', ...props }: TollerudToasterProps) => {\n const [mobile, setMobile] = useState(false)\n\n useEffect(() => {\n const check = () => setMobile(window.innerWidth < 640)\n check()\n window.addEventListener('resize', check)\n return () => window.removeEventListener('resize', check)\n }, [])\n\n return (\n <SonnerToaster\n position={mobile ? 'top-center' : 'top-right'}\n theme={theme as ToasterProps['theme']}\n className=\"toaster group\"\n toastOptions={{\n classNames: {\n toast:\n 'group toast group-[.toaster]:bg-tollerud-noir-900 group-[.toaster]:text-tollerud-foreground ' +\n 'group-[.toaster]:border group-[.toaster]:border-tollerud-border/30 ' +\n 'group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-tollerud-text-muted text-xs',\n actionButton:\n 'group-[.toast]:bg-tollerud-yellow group-[.toast]:text-tollerud-black group-[.toast]:text-xs ' +\n 'group-[.toast]:font-medium group-[.toast]:px-3 group-[.toast]:py-1 group-[.toast]:rounded',\n cancelButton:\n 'group-[.toast]:bg-tollerud-noir-800 group-[.toast]:text-tollerud-text-muted ' +\n 'group-[.toast]:text-xs group-[.toast]:px-3 group-[.toast]:py-1 group-[.toast]:rounded',\n success: 'group-[.toast]:border-l-tollerud-success group-[.toast]:border-l-2',\n error: 'group-[.toast]:border-l-tollerud-error group-[.toast]:border-l-2',\n warning: 'group-[.toast]:border-l-tollerud-yellow group-[.toast]:border-l-2',\n info: 'group-[.toast]:border-l-tollerud-info group-[.toast]:border-l-2',\n },\n }}\n {...props}\n />\n )\n}\n\nexport { Toaster }"]}
@@ -0,0 +1,53 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ var Divider = forwardRef(
7
+ ({ className, orientation = "horizontal", label, ...props }, ref) => {
8
+ if (orientation === "vertical") {
9
+ return /* @__PURE__ */ jsx(
10
+ "div",
11
+ {
12
+ ref,
13
+ role: "separator",
14
+ "aria-orientation": "vertical",
15
+ className: cn("w-px self-stretch bg-tollerud-border", className),
16
+ ...props
17
+ }
18
+ );
19
+ }
20
+ if (label) {
21
+ return /* @__PURE__ */ jsxs(
22
+ "div",
23
+ {
24
+ ref,
25
+ role: "separator",
26
+ "aria-orientation": "horizontal",
27
+ className: cn("flex items-center gap-3 text-xs text-tollerud-text-muted", className),
28
+ ...props,
29
+ children: [
30
+ /* @__PURE__ */ jsx("span", { className: "h-px flex-1 bg-tollerud-border" }),
31
+ /* @__PURE__ */ jsx("span", { children: label }),
32
+ /* @__PURE__ */ jsx("span", { className: "h-px flex-1 bg-tollerud-border" })
33
+ ]
34
+ }
35
+ );
36
+ }
37
+ return /* @__PURE__ */ jsx(
38
+ "div",
39
+ {
40
+ ref,
41
+ role: "separator",
42
+ "aria-orientation": "horizontal",
43
+ className: cn("h-px w-full bg-tollerud-border", className),
44
+ ...props
45
+ }
46
+ );
47
+ }
48
+ );
49
+ Divider.displayName = "Divider";
50
+
51
+ export { Divider };
52
+ //# sourceMappingURL=chunk-CKNWXYMA.js.map
53
+ //# sourceMappingURL=chunk-CKNWXYMA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Divider.tsx"],"names":[],"mappings":";;;;AAUA,IAAM,OAAA,GAAU,UAAA;AAAA,EACd,CAAC,EAAE,SAAA,EAAW,WAAA,GAAc,cAAc,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACnE,IAAA,IAAI,gBAAgB,UAAA,EAAY;AAC9B,MAAA,uBACE,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,IAAA,EAAK,WAAA;AAAA,UACL,kBAAA,EAAiB,UAAA;AAAA,UACjB,SAAA,EAAW,EAAA,CAAG,sCAAA,EAAwC,SAAS,CAAA;AAAA,UAC9D,GAAG;AAAA;AAAA,OACN;AAAA,IAEJ;AAEA,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,uBACE,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,IAAA,EAAK,WAAA;AAAA,UACL,kBAAA,EAAiB,YAAA;AAAA,UACjB,SAAA,EAAW,EAAA,CAAG,0DAAA,EAA4D,SAAS,CAAA;AAAA,UAClF,GAAG,KAAA;AAAA,UAEJ,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gCAAA,EAAiC,CAAA;AAAA,4BACjD,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,4BACb,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EAAiC;AAAA;AAAA;AAAA,OACnD;AAAA,IAEJ;AAEA,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA,EAAK,WAAA;AAAA,QACL,kBAAA,EAAiB,YAAA;AAAA,QACjB,SAAA,EAAW,EAAA,CAAG,gCAAA,EAAkC,SAAS,CAAA;AAAA,QACxD,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"chunk-CKNWXYMA.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface DividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Layout direction */\n orientation?: 'horizontal' | 'vertical'\n /** Optional label rendered inline (horizontal orientation only) */\n label?: React.ReactNode\n}\n\nconst Divider = forwardRef<HTMLDivElement, DividerProps>(\n ({ className, orientation = 'horizontal', label, ...props }, ref) => {\n if (orientation === 'vertical') {\n return (\n <div\n ref={ref}\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cn('w-px self-stretch bg-tollerud-border', className)}\n {...props}\n />\n )\n }\n\n if (label) {\n return (\n <div\n ref={ref}\n role=\"separator\"\n aria-orientation=\"horizontal\"\n className={cn('flex items-center gap-3 text-xs text-tollerud-text-muted', className)}\n {...props}\n >\n <span className=\"h-px flex-1 bg-tollerud-border\" />\n <span>{label}</span>\n <span className=\"h-px flex-1 bg-tollerud-border\" />\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n aria-orientation=\"horizontal\"\n className={cn('h-px w-full bg-tollerud-border', className)}\n {...props}\n />\n )\n }\n)\nDivider.displayName = 'Divider'\n\nexport { Divider }\n"]}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var Container = forwardRef(
7
+ ({ className, as: Tag = "div", ...props }, ref) => {
8
+ return /* @__PURE__ */ jsx(
9
+ Tag,
10
+ {
11
+ ref,
12
+ className: cn("mx-auto w-full max-w-[1100px] px-6", className),
13
+ ...props
14
+ }
15
+ );
16
+ }
17
+ );
18
+ Container.displayName = "Container";
19
+
20
+ export { Container };
21
+ //# sourceMappingURL=chunk-DNJI65VQ.js.map
22
+ //# sourceMappingURL=chunk-DNJI65VQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Container.tsx"],"names":[],"mappings":";;;;AAOA,IAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAC,EAAE,SAAA,EAAW,EAAA,EAAI,MAAM,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACjD,IAAA,uBACE,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA,CAAG,oCAAA,EAAsC,SAAS,CAAA;AAAA,QAC5D,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,SAAA,CAAU,WAAA,GAAc,WAAA","file":"chunk-DNJI65VQ.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface ContainerProps extends HTMLAttributes<HTMLDivElement> {\n as?: 'div' | 'section' | 'article' | 'main' | 'header' | 'footer'\n}\n\nconst Container = forwardRef<HTMLDivElement, ContainerProps>(\n ({ className, as: Tag = 'div', ...props }, ref) => {\n return (\n <Tag\n ref={ref}\n className={cn('mx-auto w-full max-w-[1100px] px-6', className)}\n {...props}\n />\n )\n }\n)\nContainer.displayName = 'Container'\n\nexport { Container }\n"]}
@@ -0,0 +1,63 @@
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 HostCard = forwardRef(
8
+ ({ className, hostname, ip, status = "online", cpu, memory, disk, uptime, containers, 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
+ loading && "animate-pulse",
20
+ className
21
+ ),
22
+ ...props,
23
+ children: [
24
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
25
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
26
+ /* @__PURE__ */ jsx(StatusDot, { status }),
27
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-sm text-tollerud-foreground truncate", children: hostname })
28
+ ] }),
29
+ containers !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-tollerud-text-muted whitespace-nowrap ml-2", children: [
30
+ containers,
31
+ " container",
32
+ containers !== 1 ? "s" : ""
33
+ ] })
34
+ ] }),
35
+ ip && /* @__PURE__ */ jsx("div", { className: "text-xs text-tollerud-text-muted mb-2 font-mono", children: ip }),
36
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-x-4 gap-y-1 text-xs text-tollerud-text-muted", children: [
37
+ cpu && /* @__PURE__ */ jsxs("span", { children: [
38
+ "CPU: ",
39
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: cpu })
40
+ ] }),
41
+ memory && /* @__PURE__ */ jsxs("span", { children: [
42
+ "RAM: ",
43
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: memory })
44
+ ] }),
45
+ disk && /* @__PURE__ */ jsxs("span", { children: [
46
+ "Disk: ",
47
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: disk })
48
+ ] }),
49
+ uptime && /* @__PURE__ */ jsxs("span", { children: [
50
+ "Up: ",
51
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary", children: uptime })
52
+ ] })
53
+ ] })
54
+ ]
55
+ }
56
+ );
57
+ }
58
+ );
59
+ HostCard.displayName = "HostCard";
60
+
61
+ export { HostCard };
62
+ //# sourceMappingURL=chunk-DOUDJU4P.js.map
63
+ //# sourceMappingURL=chunk-DOUDJU4P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/HostCard.tsx"],"names":[],"mappings":";;;;;AAyBA,IAAM,QAAA,GAAW,UAAA;AAAA,EACf,CAAC,EAAE,SAAA,EAAW,QAAA,EAAU,EAAA,EAAI,SAAS,QAAA,EAAU,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAM,QAAQ,UAAA,EAAY,OAAA,EAAS,GAAG,KAAA,IAAS,GAAA,KAAQ;AACjH,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,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,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iCAAA,EACb,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,aAAU,MAAA,EAAgB,CAAA;AAAA,8BAC3B,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yDAAA,EACb,QAAA,EAAA,QAAA,EACH;AAAA,aAAA,EACF,CAAA;AAAA,YACC,UAAA,KAAe,MAAA,oBACd,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6DAAA,EACb,QAAA,EAAA;AAAA,cAAA,UAAA;AAAA,cAAW,YAAA;AAAA,cAAW,UAAA,KAAe,IAAI,GAAA,GAAM;AAAA,aAAA,EAClD;AAAA,WAAA,EAEJ,CAAA;AAAA,UACC,EAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mDAAmD,QAAA,EAAA,EAAA,EAAG,CAAA;AAAA,0BAEvE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iEAAA,EACZ,QAAA,EAAA;AAAA,YAAA,GAAA,yBAAQ,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,8BAAK,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,GAAA,EAAI;AAAA,aAAA,EAAO,CAAA;AAAA,YAC7E,MAAA,yBAAW,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,8BAAK,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,MAAA,EAAO;AAAA,aAAA,EAAO,CAAA;AAAA,YACnF,IAAA,yBAAS,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,QAAA;AAAA,8BAAM,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,IAAA,EAAK;AAAA,aAAA,EAAO,CAAA;AAAA,YAChF,MAAA,yBAAW,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,MAAA;AAAA,8BAAI,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,MAAA,EAAO;AAAA,aAAA,EAAO;AAAA,WAAA,EACrF;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-DOUDJU4P.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\nimport { StatusDot, type Status } from './StatusDot'\n\nexport interface HostCardProps extends HTMLAttributes<HTMLDivElement> {\n /** Hostname */\n hostname: string\n /** IP address */\n ip?: string\n /** Status */\n status?: Status\n /** CPU load (e.g. '23%') */\n cpu?: string\n /** Memory usage (e.g. '6.2/16 GB') */\n memory?: string\n /** Disk usage (e.g. '45%') */\n disk?: string\n /** Uptime */\n uptime?: string\n /** Number of containers running */\n containers?: number\n /** Whether the card is loading */\n loading?: boolean\n}\n\nconst HostCard = forwardRef<HTMLDivElement, HostCardProps>(\n ({ className, hostname, ip, status = 'online', cpu, memory, disk, uptime, containers, 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 loading && 'animate-pulse',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <StatusDot status={status} />\n <span className=\"font-semibold text-sm text-tollerud-foreground truncate\">\n {hostname}\n </span>\n </div>\n {containers !== undefined && (\n <span className=\"text-[11px] text-tollerud-text-muted whitespace-nowrap ml-2\">\n {containers} container{containers !== 1 ? 's' : ''}\n </span>\n )}\n </div>\n {ip && (\n <div className=\"text-xs text-tollerud-text-muted mb-2 font-mono\">{ip}</div>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1 text-xs text-tollerud-text-muted\">\n {cpu && <span>CPU: <span className=\"text-tollerud-text-secondary\">{cpu}</span></span>}\n {memory && <span>RAM: <span className=\"text-tollerud-text-secondary\">{memory}</span></span>}\n {disk && <span>Disk: <span className=\"text-tollerud-text-secondary\">{disk}</span></span>}\n {uptime && <span>Up: <span className=\"text-tollerud-text-secondary\">{uptime}</span></span>}\n </div>\n </div>\n )\n }\n)\nHostCard.displayName = 'HostCard'\n\nexport { HostCard }\n"]}
@@ -0,0 +1,64 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef, useState, useCallback } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var CodeBlock = forwardRef(
7
+ ({ className, children, code, promptPrefix: _promptPrefix, showCopy = true, ...props }, ref) => {
8
+ const [copied, setCopied] = useState(false);
9
+ const content = code ? /* @__PURE__ */ jsx("code", { className: "text-tollerud-noir-200", children: code }) : children;
10
+ const handleCopy = useCallback(async () => {
11
+ const text = code ?? (typeof children === "string" ? children : "");
12
+ if (!text) return;
13
+ try {
14
+ await navigator.clipboard.writeText(text);
15
+ } catch {
16
+ const textarea = document.createElement("textarea");
17
+ textarea.value = text;
18
+ textarea.style.position = "fixed";
19
+ textarea.style.opacity = "0";
20
+ document.body.appendChild(textarea);
21
+ textarea.select();
22
+ document.execCommand("copy");
23
+ document.body.removeChild(textarea);
24
+ }
25
+ setCopied(true);
26
+ setTimeout(() => setCopied(false), 1500);
27
+ }, [code, children]);
28
+ return /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
29
+ /* @__PURE__ */ jsx(
30
+ "pre",
31
+ {
32
+ ref,
33
+ className: cn(
34
+ "font-mono text-sm leading-relaxed overflow-x-auto rounded border p-4",
35
+ "bg-tollerud-noir-900 border-tollerud-border text-tollerud-noir-200",
36
+ className
37
+ ),
38
+ ...props,
39
+ children: content
40
+ }
41
+ ),
42
+ showCopy && /* @__PURE__ */ jsx(
43
+ "button",
44
+ {
45
+ onClick: handleCopy,
46
+ className: cn(
47
+ "absolute top-2 right-2 px-2 py-1 rounded text-xs font-medium",
48
+ "opacity-0 group-hover:opacity-100 transition-all",
49
+ "bg-tollerud-noir-800 border border-tollerud-border/30 text-tollerud-text-muted",
50
+ "hover:bg-tollerud-surface-raised hover:text-tollerud-text-primary",
51
+ copied && "opacity-100 bg-tollerud-success/15 text-tollerud-success border-tollerud-success/40"
52
+ ),
53
+ "aria-label": copied ? "Copied" : "Copy code",
54
+ children: copied ? "\u2713 Copied" : "Copy"
55
+ }
56
+ )
57
+ ] });
58
+ }
59
+ );
60
+ CodeBlock.displayName = "CodeBlock";
61
+
62
+ export { CodeBlock };
63
+ //# sourceMappingURL=chunk-DRCMGIQ6.js.map
64
+ //# sourceMappingURL=chunk-DRCMGIQ6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/CodeBlock.tsx"],"names":[],"mappings":";;;;AAcA,IAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAC,EAAE,SAAA,EAAW,QAAA,EAAU,IAAA,EAAM,YAAA,EAAc,aAAA,EAAe,QAAA,GAAW,IAAA,EAAM,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC9F,IAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAE1C,IAAA,MAAM,UAAU,IAAA,mBACd,GAAA,CAAC,UAAK,SAAA,EAAU,wBAAA,EAA0B,gBAAK,CAAA,GAE/C,QAAA;AAGF,IAAA,MAAM,UAAA,GAAa,YAAY,YAAY;AACzC,MAAA,MAAM,IAAA,GAAO,IAAA,KAAS,OAAO,QAAA,KAAa,WAAW,QAAA,GAAW,EAAA,CAAA;AAChE,MAAA,IAAI,CAAC,IAAA,EAAM;AAGX,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AAAA,MAC1C,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,UAAU,CAAA;AAClD,QAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AACjB,QAAA,QAAA,CAAS,MAAM,QAAA,GAAW,OAAA;AAC1B,QAAA,QAAA,CAAS,MAAM,OAAA,GAAU,GAAA;AACzB,QAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAClC,QAAA,QAAA,CAAS,MAAA,EAAO;AAChB,QAAA,QAAA,CAAS,YAAY,MAAM,CAAA;AAC3B,QAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAAA,MACpC;AAEA,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,CAAA,EAAG,IAAI,CAAA;AAAA,IACzC,CAAA,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEnB,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,SAAA,EAAW,EAAA;AAAA,YACT,sEAAA;AAAA,YACA,oEAAA;AAAA,YACA;AAAA,WACF;AAAA,UACC,GAAG,KAAA;AAAA,UAEH,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,MACC,QAAA,oBACC,GAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,UAAA;AAAA,UACT,SAAA,EAAW,EAAA;AAAA,YACT,8DAAA;AAAA,YACA,kDAAA;AAAA,YACA,gFAAA;AAAA,YACA,mEAAA;AAAA,YACA,MAAA,IAAU;AAAA,WACZ;AAAA,UACA,YAAA,EAAY,SAAS,QAAA,GAAW,WAAA;AAAA,UAE/B,mBAAS,eAAA,GAAa;AAAA;AAAA;AACzB,KAAA,EAEJ,CAAA;AAAA,EAEJ;AACF;AACA,SAAA,CAAU,WAAA,GAAc,WAAA","file":"chunk-DRCMGIQ6.js","sourcesContent":["'use client'\n\nimport { type HTMLAttributes, forwardRef, useState, useCallback } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface CodeBlockProps extends HTMLAttributes<HTMLPreElement> {\n /** Optional string content to render inside <code> tags */\n code?: string\n /** When true, prepends a prompt symbol ($) before text content */\n promptPrefix?: boolean\n /** When false, hides the copy-to-clipboard button (default: true) */\n showCopy?: boolean\n}\n\nconst CodeBlock = forwardRef<HTMLPreElement, CodeBlockProps>(\n ({ className, children, code, promptPrefix: _promptPrefix, showCopy = true, ...props }, ref) => {\n const [copied, setCopied] = useState(false)\n\n const content = code ? (\n <code className=\"text-tollerud-noir-200\">{code}</code>\n ) : (\n children\n )\n\n const handleCopy = useCallback(async () => {\n const text = code ?? (typeof children === 'string' ? children : '')\n if (!text) return\n\n // Try clipboard API first, fallback to execCommand for broader compat\n try {\n await navigator.clipboard.writeText(text)\n } catch {\n const textarea = document.createElement('textarea')\n textarea.value = text\n textarea.style.position = 'fixed'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n textarea.select()\n document.execCommand('copy')\n document.body.removeChild(textarea)\n }\n\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n }, [code, children])\n\n return (\n <div className=\"relative group\">\n <pre\n ref={ref}\n className={cn(\n 'font-mono text-sm leading-relaxed overflow-x-auto rounded border p-4',\n 'bg-tollerud-noir-900 border-tollerud-border text-tollerud-noir-200',\n className\n )}\n {...props}\n >\n {content}\n </pre>\n {showCopy && (\n <button\n onClick={handleCopy}\n className={cn(\n 'absolute top-2 right-2 px-2 py-1 rounded text-xs font-medium',\n 'opacity-0 group-hover:opacity-100 transition-all',\n 'bg-tollerud-noir-800 border border-tollerud-border/30 text-tollerud-text-muted',\n 'hover:bg-tollerud-surface-raised hover:text-tollerud-text-primary',\n copied && 'opacity-100 bg-tollerud-success/15 text-tollerud-success border-tollerud-success/40'\n )}\n aria-label={copied ? 'Copied' : 'Copy code'}\n >\n {copied ? '✓ Copied' : 'Copy'}\n </button>\n )}\n </div>\n )\n }\n)\nCodeBlock.displayName = 'CodeBlock'\n\nexport { CodeBlock }\n"]}
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var Card = forwardRef(
7
+ ({ className, accent, density, ...props }, ref) => {
8
+ return /* @__PURE__ */ jsx(
9
+ "div",
10
+ {
11
+ ref,
12
+ "data-density": density ?? void 0,
13
+ className: cn(
14
+ "rounded-lg border bg-tollerud-surface-raised p-6 transition-[border-color] duration-[150ms]",
15
+ accent ? "border-tollerud-yellow/25" : "border-tollerud-border",
16
+ "hover:border-tollerud-noir-500",
17
+ className
18
+ ),
19
+ ...props
20
+ }
21
+ );
22
+ }
23
+ );
24
+ Card.displayName = "Card";
25
+
26
+ export { Card };
27
+ //# sourceMappingURL=chunk-DZOBXK2S.js.map
28
+ //# sourceMappingURL=chunk-DZOBXK2S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Card.tsx"],"names":[],"mappings":";;;;AAQA,IAAM,IAAA,GAAO,UAAA;AAAA,EACX,CAAC,EAAE,SAAA,EAAW,MAAA,EAAQ,SAAS,GAAG,KAAA,IAAS,GAAA,KAAQ;AACjD,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,gBAAc,OAAA,IAAW,MAAA;AAAA,QACzB,SAAA,EAAW,EAAA;AAAA,UACT,6FAAA;AAAA,UACA,SAAS,2BAAA,GAA8B,wBAAA;AAAA,UACvC,gCAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,IAAA,CAAK,WAAA,GAAc,MAAA","file":"chunk-DZOBXK2S.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface CardProps extends HTMLAttributes<HTMLDivElement> {\n accent?: boolean\n density?: 'comfortable' | 'compact'\n}\n\nconst Card = forwardRef<HTMLDivElement, CardProps>(\n ({ className, accent, density, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-density={density ?? undefined}\n className={cn(\n 'rounded-lg border bg-tollerud-surface-raised p-6 transition-[border-color] duration-[150ms]',\n accent ? 'border-tollerud-yellow/25' : 'border-tollerud-border',\n 'hover:border-tollerud-noir-500',\n className\n )}\n {...props}\n />\n )\n }\n)\nCard.displayName = 'Card'\n\nexport { Card }\n"]}
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ var severityStyles = {
7
+ critical: { border: "border-tollerud-error/50", dot: "bg-tollerud-error shadow-[0_0_8px_rgba(239,68,68,0.6)]", label: "text-tollerud-error" },
8
+ high: { border: "border-tollerud-yellow/50", dot: "bg-tollerud-yellow shadow-[0_0_8px_rgba(232,213,0,0.5)]", label: "text-tollerud-yellow" },
9
+ medium: { border: "border-tollerud-amber/40", dot: "bg-tollerud-amber", label: "text-tollerud-amber" },
10
+ low: { border: "border-tollerud-noir-500", dot: "bg-tollerud-noir-400", label: "text-tollerud-text-muted" },
11
+ info: { border: "border-tollerud-info/30", dot: "bg-tollerud-info", label: "text-tollerud-info" }
12
+ };
13
+ var IncidentCard = forwardRef(
14
+ ({ className, title, severity, timestamp, description, service, acknowledged, loading, ...props }, ref) => {
15
+ const style = severityStyles[severity];
16
+ return /* @__PURE__ */ jsx(
17
+ "div",
18
+ {
19
+ ref,
20
+ className: cn(
21
+ "rounded-lg border bg-tollerud-surface-raised p-4",
22
+ "transition-[border-color] duration-[150ms]",
23
+ style.border,
24
+ acknowledged && "opacity-50",
25
+ loading && "animate-pulse",
26
+ className
27
+ ),
28
+ ...props,
29
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
30
+ /* @__PURE__ */ jsx("span", { className: cn("w-2 h-2 rounded-full mt-1.5 flex-shrink-0", style.dot) }),
31
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
32
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
33
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-tollerud-foreground truncate", children: title }),
34
+ /* @__PURE__ */ jsx("span", { className: cn("text-[11px] font-medium uppercase whitespace-nowrap", style.label), children: severity })
35
+ ] }),
36
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-0.5 text-xs text-tollerud-text-muted", children: [
37
+ /* @__PURE__ */ jsx("span", { children: timestamp }),
38
+ service && /* @__PURE__ */ jsxs(Fragment, { children: [
39
+ /* @__PURE__ */ jsx("span", { className: "text-tollerud-noir-500", children: "\xB7" }),
40
+ /* @__PURE__ */ jsx("span", { children: service })
41
+ ] })
42
+ ] }),
43
+ description && /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-xs text-tollerud-text-secondary leading-relaxed", children: description })
44
+ ] })
45
+ ] })
46
+ }
47
+ );
48
+ }
49
+ );
50
+ IncidentCard.displayName = "IncidentCard";
51
+
52
+ export { IncidentCard };
53
+ //# sourceMappingURL=chunk-EN4OJCEF.js.map
54
+ //# sourceMappingURL=chunk-EN4OJCEF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/IncidentCard.tsx"],"names":[],"mappings":";;;;AAsBA,IAAM,cAAA,GAA2F;AAAA,EAC/F,UAAU,EAAE,MAAA,EAAQ,4BAA4B,GAAA,EAAK,wDAAA,EAA0D,OAAO,qBAAA,EAAsB;AAAA,EAC5I,MAAU,EAAE,MAAA,EAAQ,6BAA6B,GAAA,EAAK,yDAAA,EAA2D,OAAO,sBAAA,EAAuB;AAAA,EAC/I,QAAU,EAAE,MAAA,EAAQ,4BAA4B,GAAA,EAAK,mBAAA,EAAqB,OAAO,qBAAA,EAAsB;AAAA,EACvG,KAAU,EAAE,MAAA,EAAQ,4BAA4B,GAAA,EAAK,sBAAA,EAAwB,OAAO,0BAAA,EAA2B;AAAA,EAC/G,MAAU,EAAE,MAAA,EAAQ,2BAA2B,GAAA,EAAK,kBAAA,EAAoB,OAAO,oBAAA;AACjF,CAAA;AAEA,IAAM,YAAA,GAAe,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,WAAA,EAAa,OAAA,EAAS,YAAA,EAAc,OAAA,EAAS,GAAG,KAAA,IAAS,GAAA,KAAQ;AACzG,IAAA,MAAM,KAAA,GAAQ,eAAe,QAAQ,CAAA;AAErC,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,kDAAA;AAAA,UACA,4CAAA;AAAA,UACA,KAAA,CAAM,MAAA;AAAA,UACN,YAAA,IAAgB,YAAA;AAAA,UAChB,OAAA,IAAW,eAAA;AAAA,UACX;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACb,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,2CAAA,EAA6C,KAAA,CAAM,GAAG,CAAA,EAAG,CAAA;AAAA,0BAC7E,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yCAAA,EACb,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yDAAA,EAA2D,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,8BACjF,GAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,uDAAuD,KAAA,CAAM,KAAK,GACnF,QAAA,EAAA,QAAA,EACH;AAAA,aAAA,EACF,CAAA;AAAA,4BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iEAAA,EACb,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,UAAM,QAAA,EAAA,SAAA,EAAU,CAAA;AAAA,cAChB,2BAAW,IAAA,CAAA,QAAA,EAAA,EAAE,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAAyB,QAAA,EAAA,MAAA,EAAC,CAAA;AAAA,gCAAO,GAAA,CAAC,UAAM,QAAA,EAAA,OAAA,EAAQ;AAAA,eAAA,EAAO;AAAA,aAAA,EACvF,CAAA;AAAA,YACC,WAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+DAA+D,QAAA,EAAA,WAAA,EAAY;AAAA,WAAA,EAE5F;AAAA,SAAA,EACF;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,YAAA,CAAa,WAAA,GAAc,cAAA","file":"chunk-EN4OJCEF.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport type IncidentSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info'\n\nexport interface IncidentCardProps extends HTMLAttributes<HTMLDivElement> {\n /** Incident title */\n title: string\n /** Severity level */\n severity: IncidentSeverity\n /** Timestamp string */\n timestamp: string\n /** Description / detail */\n description?: string\n /** Service name affected */\n service?: string\n /** Whether acknowledged */\n acknowledged?: boolean\n /** Whether the card is loading */\n loading?: boolean\n}\n\nconst severityStyles: Record<IncidentSeverity, { border: string; dot: string; label: string }> = {\n critical: { border: 'border-tollerud-error/50', dot: 'bg-tollerud-error shadow-[0_0_8px_rgba(239,68,68,0.6)]', label: 'text-tollerud-error' },\n high: { border: 'border-tollerud-yellow/50', dot: 'bg-tollerud-yellow shadow-[0_0_8px_rgba(232,213,0,0.5)]', label: 'text-tollerud-yellow' },\n medium: { border: 'border-tollerud-amber/40', dot: 'bg-tollerud-amber', label: 'text-tollerud-amber' },\n low: { border: 'border-tollerud-noir-500', dot: 'bg-tollerud-noir-400', label: 'text-tollerud-text-muted' },\n info: { border: 'border-tollerud-info/30', dot: 'bg-tollerud-info', label: 'text-tollerud-info' },\n}\n\nconst IncidentCard = forwardRef<HTMLDivElement, IncidentCardProps>(\n ({ className, title, severity, timestamp, description, service, acknowledged, loading, ...props }, ref) => {\n const style = severityStyles[severity]\n\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 style.border,\n acknowledged && 'opacity-50',\n loading && 'animate-pulse',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start gap-3\">\n <span className={cn('w-2 h-2 rounded-full mt-1.5 flex-shrink-0', style.dot)} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-tollerud-foreground truncate\">{title}</span>\n <span className={cn('text-[11px] font-medium uppercase whitespace-nowrap', style.label)}>\n {severity}\n </span>\n </div>\n <div className=\"flex items-center gap-2 mt-0.5 text-xs text-tollerud-text-muted\">\n <span>{timestamp}</span>\n {service && <><span className=\"text-tollerud-noir-500\">·</span><span>{service}</span></>}\n </div>\n {description && (\n <p className=\"mt-1.5 text-xs text-tollerud-text-secondary leading-relaxed\">{description}</p>\n )}\n </div>\n </div>\n </div>\n )\n }\n)\nIncidentCard.displayName = 'IncidentCard'\n\nexport { IncidentCard }\n"]}
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { cn } from './chunk-WSQNPRGN.js';
3
+ import { forwardRef } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var Sparkline = forwardRef(
7
+ ({ className, data, width, height, w, h, color = "#E8D500", ...props }, ref) => {
8
+ const resolvedWidth = width ?? w ?? 120;
9
+ const resolvedHeight = height ?? h ?? 34;
10
+ const max = Math.max(...data);
11
+ const min = Math.min(...data);
12
+ const span = Math.max(data.length - 1, 1);
13
+ const pts = data.map(
14
+ (v, i) => `${i / span * resolvedWidth},${resolvedHeight - 2 - (v - min) / (max - min || 1) * (resolvedHeight - 4)}`
15
+ ).join(" ");
16
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("inline-block", className), ...props, children: /* @__PURE__ */ jsx("svg", { width: resolvedWidth, height: resolvedHeight, className: "block", role: "img", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
17
+ "polyline",
18
+ {
19
+ points: pts,
20
+ fill: "none",
21
+ stroke: color,
22
+ strokeWidth: "1.6",
23
+ strokeLinecap: "round",
24
+ strokeLinejoin: "round"
25
+ }
26
+ ) }) });
27
+ }
28
+ );
29
+ Sparkline.displayName = "Sparkline";
30
+
31
+ export { Sparkline };
32
+ //# sourceMappingURL=chunk-EVHZFYWX.js.map
33
+ //# sourceMappingURL=chunk-EVHZFYWX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../components/Sparkline.tsx"],"names":[],"mappings":";;;;AAcA,IAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG,KAAA,GAAQ,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAC9E,IAAA,MAAM,aAAA,GAAgB,SAAS,CAAA,IAAK,GAAA;AACpC,IAAA,MAAM,cAAA,GAAiB,UAAU,CAAA,IAAK,EAAA;AACtC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,IAAI,CAAA;AAC5B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,IAAI,CAAA;AAC5B,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,GAAS,GAAG,CAAC,CAAA;AACxC,IAAA,MAAM,MAAM,IAAA,CACT,GAAA;AAAA,MACC,CAAC,CAAA,EAAG,CAAA,KACF,CAAA,EAAI,CAAA,GAAI,OAAQ,aAAa,CAAA,CAAA,EAAI,cAAA,GAAiB,CAAA,GAAA,CAAM,IAAI,GAAA,KAAQ,GAAA,GAAM,GAAA,IAAO,CAAA,CAAA,IAAO,iBAAiB,CAAA,CAAE,CAAA;AAAA,KAC/G,CACC,KAAK,GAAG,CAAA;AAEX,IAAA,uBACE,GAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,cAAA,EAAgB,SAAS,GAAI,GAAG,KAAA,EAC3D,8BAAC,KAAA,EAAA,EAAI,KAAA,EAAO,eAAe,MAAA,EAAQ,cAAA,EAAgB,WAAU,OAAA,EAAQ,IAAA,EAAK,KAAA,EAAM,aAAA,EAAY,MAAA,EAC1F,QAAA,kBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ,GAAA;AAAA,QACR,IAAA,EAAK,MAAA;AAAA,QACL,MAAA,EAAQ,KAAA;AAAA,QACR,WAAA,EAAY,KAAA;AAAA,QACZ,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe;AAAA;AAAA,OAEnB,CAAA,EACF,CAAA;AAAA,EAEJ;AACF;AACA,SAAA,CAAU,WAAA,GAAc,WAAA","file":"chunk-EVHZFYWX.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface SparklineProps extends HTMLAttributes<HTMLDivElement> {\n data: number[]\n width?: number\n height?: number\n /** @deprecated Use `width` */\n w?: number\n /** @deprecated Use `height` */\n h?: number\n color?: string\n}\n\nconst Sparkline = forwardRef<HTMLDivElement, SparklineProps>(\n ({ className, data, width, height, w, h, color = '#E8D500', ...props }, ref) => {\n const resolvedWidth = width ?? w ?? 120\n const resolvedHeight = height ?? h ?? 34\n const max = Math.max(...data)\n const min = Math.min(...data)\n const span = Math.max(data.length - 1, 1)\n const pts = data\n .map(\n (v, i) =>\n `${(i / span) * resolvedWidth},${resolvedHeight - 2 - ((v - min) / (max - min || 1)) * (resolvedHeight - 4)}`\n )\n .join(' ')\n\n return (\n <div ref={ref} className={cn('inline-block', className)} {...props}>\n <svg width={resolvedWidth} height={resolvedHeight} className=\"block\" role=\"img\" aria-hidden=\"true\">\n <polyline\n points={pts}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n )\n }\n)\nSparkline.displayName = 'Sparkline'\n\nexport { Sparkline }\n"]}