@sero-ai/ui 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/.turbo/turbo-build.log +615 -0
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/CHANGELOG.md +58 -0
  4. package/dist/components/context-editor/CapabilitySection.cjs +57 -0
  5. package/dist/components/context-editor/CapabilitySection.d.cts +20 -0
  6. package/dist/components/context-editor/CapabilitySection.d.ts +20 -0
  7. package/dist/components/context-editor/CapabilitySection.js +57 -0
  8. package/dist/components/context-editor/ContextEditor.cjs +108 -0
  9. package/dist/components/context-editor/ContextEditor.d.cts +26 -0
  10. package/dist/components/context-editor/ContextEditor.d.ts +26 -0
  11. package/dist/components/context-editor/ContextEditor.js +108 -0
  12. package/dist/components/context-editor/PresetBar.cjs +71 -0
  13. package/dist/components/context-editor/PresetBar.d.cts +19 -0
  14. package/dist/components/context-editor/PresetBar.d.ts +19 -0
  15. package/dist/components/context-editor/PresetBar.js +71 -0
  16. package/dist/components/context-editor/SkillsSection.cjs +31 -0
  17. package/dist/components/context-editor/SkillsSection.d.cts +14 -0
  18. package/dist/components/context-editor/SkillsSection.d.ts +14 -0
  19. package/dist/components/context-editor/SkillsSection.js +31 -0
  20. package/dist/components/context-editor/SystemPromptSection.cjs +58 -0
  21. package/dist/components/context-editor/SystemPromptSection.d.cts +25 -0
  22. package/dist/components/context-editor/SystemPromptSection.d.ts +25 -0
  23. package/dist/components/context-editor/SystemPromptSection.js +58 -0
  24. package/dist/components/context-editor/ToolsSection.cjs +31 -0
  25. package/dist/components/context-editor/ToolsSection.d.cts +14 -0
  26. package/dist/components/context-editor/ToolsSection.d.ts +14 -0
  27. package/dist/components/context-editor/ToolsSection.js +31 -0
  28. package/dist/components/context-editor/index.cjs +8 -0
  29. package/dist/components/context-editor/index.d.cts +5 -0
  30. package/dist/components/context-editor/index.d.ts +5 -0
  31. package/dist/components/context-editor/index.js +8 -0
  32. package/dist/components/context-editor/parts.cjs +184 -0
  33. package/dist/components/context-editor/parts.d.cts +32 -0
  34. package/dist/components/context-editor/parts.d.ts +32 -0
  35. package/dist/components/context-editor/parts.js +184 -0
  36. package/dist/components/context-editor/use-context-editor-model.cjs +194 -0
  37. package/dist/components/context-editor/use-context-editor-model.d.cts +57 -0
  38. package/dist/components/context-editor/use-context-editor-model.d.ts +57 -0
  39. package/dist/components/context-editor/use-context-editor-model.js +194 -0
  40. package/dist/components/dashboard/activity-list.cjs +59 -0
  41. package/dist/components/dashboard/activity-list.d.cts +27 -0
  42. package/dist/components/dashboard/activity-list.d.ts +27 -0
  43. package/dist/components/dashboard/activity-list.js +59 -0
  44. package/dist/components/dashboard/catalog.cjs +1 -0
  45. package/dist/components/dashboard/catalog.d.cts +13 -0
  46. package/dist/components/dashboard/catalog.d.ts +13 -0
  47. package/dist/components/dashboard/catalog.js +0 -0
  48. package/dist/components/dashboard/catalog.json +312 -0
  49. package/dist/components/dashboard/data-boundary.cjs +29 -0
  50. package/dist/components/dashboard/data-boundary.d.cts +21 -0
  51. package/dist/components/dashboard/data-boundary.d.ts +21 -0
  52. package/dist/components/dashboard/data-boundary.js +29 -0
  53. package/dist/components/dashboard/empty-state.cjs +49 -0
  54. package/dist/components/dashboard/empty-state.d.cts +20 -0
  55. package/dist/components/dashboard/empty-state.d.ts +20 -0
  56. package/dist/components/dashboard/empty-state.js +49 -0
  57. package/dist/components/dashboard/icon-button.cjs +40 -0
  58. package/dist/components/dashboard/icon-button.d.cts +24 -0
  59. package/dist/components/dashboard/icon-button.d.ts +24 -0
  60. package/dist/components/dashboard/icon-button.js +40 -0
  61. package/dist/components/dashboard/index.cjs +15 -0
  62. package/dist/components/dashboard/index.d.cts +24 -0
  63. package/dist/components/dashboard/index.d.ts +24 -0
  64. package/dist/components/dashboard/index.js +15 -0
  65. package/dist/components/dashboard/item-list.cjs +71 -0
  66. package/dist/components/dashboard/item-list.d.cts +28 -0
  67. package/dist/components/dashboard/item-list.d.ts +28 -0
  68. package/dist/components/dashboard/item-list.js +71 -0
  69. package/dist/components/dashboard/key-value.cjs +39 -0
  70. package/dist/components/dashboard/key-value.d.cts +17 -0
  71. package/dist/components/dashboard/key-value.d.ts +17 -0
  72. package/dist/components/dashboard/key-value.js +39 -0
  73. package/dist/components/dashboard/layout.cjs +193 -0
  74. package/dist/components/dashboard/layout.d.cts +91 -0
  75. package/dist/components/dashboard/layout.d.ts +91 -0
  76. package/dist/components/dashboard/layout.js +193 -0
  77. package/dist/components/dashboard/metric.cjs +98 -0
  78. package/dist/components/dashboard/metric.d.cts +44 -0
  79. package/dist/components/dashboard/metric.d.ts +44 -0
  80. package/dist/components/dashboard/metric.js +98 -0
  81. package/dist/components/dashboard/progress-ring.cjs +77 -0
  82. package/dist/components/dashboard/progress-ring.d.cts +25 -0
  83. package/dist/components/dashboard/progress-ring.d.ts +25 -0
  84. package/dist/components/dashboard/progress-ring.js +77 -0
  85. package/dist/components/dashboard/skeletons.cjs +54 -0
  86. package/dist/components/dashboard/skeletons.d.cts +15 -0
  87. package/dist/components/dashboard/skeletons.d.ts +15 -0
  88. package/dist/components/dashboard/skeletons.js +54 -0
  89. package/dist/components/dashboard/spacing.cjs +10 -0
  90. package/dist/components/dashboard/spacing.d.cts +4 -0
  91. package/dist/components/dashboard/spacing.d.ts +4 -0
  92. package/dist/components/dashboard/spacing.js +10 -0
  93. package/dist/components/dashboard/stale-indicator.cjs +42 -0
  94. package/dist/components/dashboard/stale-indicator.d.cts +15 -0
  95. package/dist/components/dashboard/stale-indicator.d.ts +15 -0
  96. package/dist/components/dashboard/stale-indicator.js +42 -0
  97. package/dist/components/dashboard/status.cjs +66 -0
  98. package/dist/components/dashboard/status.d.cts +15 -0
  99. package/dist/components/dashboard/status.d.ts +15 -0
  100. package/dist/components/dashboard/status.js +66 -0
  101. package/dist/components/dashboard/tone.cjs +34 -0
  102. package/dist/components/dashboard/tone.d.cts +15 -0
  103. package/dist/components/dashboard/tone.d.ts +15 -0
  104. package/dist/components/dashboard/tone.js +34 -0
  105. package/dist/components/dashboard/typography.cjs +99 -0
  106. package/dist/components/dashboard/typography.d.cts +57 -0
  107. package/dist/components/dashboard/typography.d.ts +57 -0
  108. package/dist/components/dashboard/typography.js +99 -0
  109. package/dist/components/ui/badge.cjs +5 -1
  110. package/dist/components/ui/badge.d.cts +1 -1
  111. package/dist/components/ui/badge.d.ts +1 -1
  112. package/dist/components/ui/badge.js +5 -1
  113. package/dist/index.cjs +1 -0
  114. package/dist/index.d.cts +16 -0
  115. package/dist/index.d.ts +16 -0
  116. package/dist/index.js +1 -0
  117. package/dist/reference.cjs +1260 -0
  118. package/dist/reference.d.cts +11 -0
  119. package/dist/reference.d.ts +11 -0
  120. package/dist/reference.js +1230 -0
  121. package/dist/styles/glass-board.css +43 -0
  122. package/dist/styles/globals.css +59 -0
  123. package/package.json +16 -4
  124. package/scripts/ensure-pnpm-publish.mjs +23 -0
  125. package/scripts/smoke-dist.mjs +68 -0
  126. package/src/components/context-editor/CapabilitySection.tsx +85 -0
  127. package/src/components/context-editor/ContextEditor.tsx +138 -0
  128. package/src/components/context-editor/PresetBar.tsx +94 -0
  129. package/src/components/context-editor/SkillsSection.tsx +37 -0
  130. package/src/components/context-editor/SystemPromptSection.tsx +88 -0
  131. package/src/components/context-editor/ToolsSection.tsx +37 -0
  132. package/src/components/context-editor/index.ts +7 -0
  133. package/src/components/context-editor/parts.tsx +217 -0
  134. package/src/components/context-editor/use-context-editor-model.ts +296 -0
  135. package/src/components/dashboard/__tests__/catalog.test.ts +62 -0
  136. package/src/components/dashboard/__tests__/glass.test.tsx +42 -0
  137. package/src/components/dashboard/__tests__/state.test.tsx +127 -0
  138. package/src/components/dashboard/__tests__/variants.test.tsx +95 -0
  139. package/src/components/dashboard/activity-list.tsx +99 -0
  140. package/src/components/dashboard/catalog.json +312 -0
  141. package/src/components/dashboard/catalog.ts +29 -0
  142. package/src/components/dashboard/data-boundary.tsx +54 -0
  143. package/src/components/dashboard/empty-state.tsx +70 -0
  144. package/src/components/dashboard/icon-button.tsx +58 -0
  145. package/src/components/dashboard/index.ts +21 -0
  146. package/src/components/dashboard/item-list.tsx +106 -0
  147. package/src/components/dashboard/key-value.tsx +54 -0
  148. package/src/components/dashboard/layout.tsx +286 -0
  149. package/src/components/dashboard/metric.tsx +139 -0
  150. package/src/components/dashboard/progress-ring.tsx +100 -0
  151. package/src/components/dashboard/skeletons.tsx +73 -0
  152. package/src/components/dashboard/spacing.ts +14 -0
  153. package/src/components/dashboard/stale-indicator.tsx +55 -0
  154. package/src/components/dashboard/status.tsx +88 -0
  155. package/src/components/dashboard/tone.ts +48 -0
  156. package/src/components/dashboard/typography.tsx +151 -0
  157. package/src/components/reference/ActivityExample.tsx +68 -0
  158. package/src/components/reference/ResourceExample.tsx +78 -0
  159. package/src/components/reference/SchedulerExample.tsx +88 -0
  160. package/src/components/reference/StarterExample.tsx +48 -0
  161. package/src/components/reference/index.ts +10 -0
  162. package/src/components/ui/badge.tsx +6 -0
  163. package/src/index.ts +7 -0
  164. package/src/reference.ts +15 -0
  165. package/src/styles/glass-board.css +43 -0
  166. package/src/styles/globals.css +59 -0
  167. package/tsup.config.ts +18 -4
  168. package/tsup.reference.config.ts +15 -0
  169. package/vitest.config.ts +8 -0
@@ -0,0 +1,1230 @@
1
+ // src/components/reference/StarterExample.tsx
2
+ import { CheckCircle2 } from "lucide-react";
3
+
4
+ // src/components/dashboard/tone.ts
5
+ var toneColor = {
6
+ neutral: "text-[var(--text-muted)]",
7
+ success: "text-[var(--status-success)]",
8
+ warning: "text-[var(--status-warning)]",
9
+ error: "text-[var(--status-error)]",
10
+ info: "text-[var(--status-info)]"
11
+ };
12
+ var toneDot = {
13
+ neutral: "bg-[var(--text-muted)]",
14
+ success: "bg-[var(--status-success)]",
15
+ warning: "bg-[var(--status-warning)]",
16
+ error: "bg-[var(--status-error)]",
17
+ info: "bg-[var(--status-info)]"
18
+ };
19
+ var toneLabel = {
20
+ neutral: "Neutral",
21
+ success: "Success",
22
+ warning: "Warning",
23
+ error: "Error",
24
+ info: "Info"
25
+ };
26
+ var tonePill = {
27
+ neutral: "bg-[var(--surface-flat)] text-[var(--text-secondary)]",
28
+ success: "bg-[var(--status-success-muted)] text-[var(--status-success)]",
29
+ warning: "bg-[var(--status-warning-muted)] text-[var(--status-warning)]",
30
+ error: "bg-[var(--status-error-muted)] text-[var(--status-error)]",
31
+ info: "bg-[var(--status-info-muted)] text-[var(--status-info)]"
32
+ };
33
+
34
+ // src/components/dashboard/spacing.ts
35
+ var gapClass = {
36
+ none: "gap-0",
37
+ xs: "gap-1",
38
+ sm: "gap-2",
39
+ md: "gap-3",
40
+ lg: "gap-4"
41
+ };
42
+
43
+ // src/components/dashboard/layout.tsx
44
+ import { cva } from "class-variance-authority";
45
+
46
+ // src/lib/utils.ts
47
+ import { clsx } from "clsx";
48
+ import { twMerge } from "tailwind-merge";
49
+ function cn(...inputs) {
50
+ return twMerge(clsx(inputs));
51
+ }
52
+
53
+ // src/components/ui/separator.tsx
54
+ import { Separator as SeparatorPrimitive } from "radix-ui";
55
+ import { jsx } from "react/jsx-runtime";
56
+ function Separator({
57
+ className,
58
+ orientation = "horizontal",
59
+ decorative = true,
60
+ ...props
61
+ }) {
62
+ return /* @__PURE__ */ jsx(
63
+ SeparatorPrimitive.Root,
64
+ {
65
+ "data-slot": "separator",
66
+ decorative,
67
+ orientation,
68
+ className: cn(
69
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
70
+ className
71
+ ),
72
+ ...props
73
+ }
74
+ );
75
+ }
76
+
77
+ // src/components/dashboard/layout.tsx
78
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
79
+ var widgetContentVariants = cva(
80
+ // Full-height frame with a container-query boundary so child components can
81
+ // respond to the widget's own size rather than the viewport.
82
+ "@container/widget flex h-full min-h-0 flex-col",
83
+ {
84
+ variants: {
85
+ padding: {
86
+ none: "p-0",
87
+ sm: "p-2",
88
+ md: "p-3",
89
+ lg: "p-4"
90
+ },
91
+ scroll: {
92
+ true: "overflow-auto",
93
+ false: "overflow-hidden"
94
+ }
95
+ },
96
+ defaultVariants: { padding: "md", scroll: false }
97
+ }
98
+ );
99
+ function WidgetContent({
100
+ className,
101
+ padding,
102
+ scroll,
103
+ glass = true,
104
+ ...props
105
+ }) {
106
+ return /* @__PURE__ */ jsx2(
107
+ "div",
108
+ {
109
+ "data-slot": "widget-content",
110
+ className: cn(widgetContentVariants({ padding, scroll }), glass && "glass", className),
111
+ ...props
112
+ }
113
+ );
114
+ }
115
+ var alignClass = {
116
+ start: "items-start",
117
+ center: "items-center",
118
+ end: "items-end",
119
+ stretch: "items-stretch"
120
+ };
121
+ var justifyClass = {
122
+ start: "justify-start",
123
+ center: "justify-center",
124
+ end: "justify-end",
125
+ between: "justify-between",
126
+ around: "justify-around"
127
+ };
128
+ function Stack({
129
+ className,
130
+ gap = "sm",
131
+ align,
132
+ justify,
133
+ fill = false,
134
+ scroll = false,
135
+ ...props
136
+ }) {
137
+ return /* @__PURE__ */ jsx2(
138
+ "div",
139
+ {
140
+ "data-slot": "stack",
141
+ className: cn(
142
+ "flex flex-col",
143
+ gapClass[gap],
144
+ align && alignClass[align],
145
+ justify && justifyClass[justify],
146
+ (fill || scroll) && "min-h-0 flex-1",
147
+ scroll && "overflow-auto",
148
+ className
149
+ ),
150
+ ...props
151
+ }
152
+ );
153
+ }
154
+ function Inline({
155
+ className,
156
+ gap = "sm",
157
+ align = "center",
158
+ justify,
159
+ wrap = false,
160
+ ...props
161
+ }) {
162
+ return /* @__PURE__ */ jsx2(
163
+ "div",
164
+ {
165
+ "data-slot": "inline",
166
+ className: cn(
167
+ "flex flex-row",
168
+ gapClass[gap],
169
+ alignClass[align],
170
+ justify && justifyClass[justify],
171
+ wrap ? "flex-wrap" : "min-w-0",
172
+ className
173
+ ),
174
+ ...props
175
+ }
176
+ );
177
+ }
178
+ var columnsClass = {
179
+ 1: "grid-cols-1",
180
+ 2: "grid-cols-2",
181
+ 3: "grid-cols-3",
182
+ 4: "grid-cols-4"
183
+ };
184
+ function Grid({
185
+ className,
186
+ columns = "auto",
187
+ gap = "sm",
188
+ minColumnWidth = 120,
189
+ style,
190
+ ...props
191
+ }) {
192
+ const auto = columns === "auto";
193
+ return /* @__PURE__ */ jsx2(
194
+ "div",
195
+ {
196
+ "data-slot": "grid",
197
+ className: cn(
198
+ "grid",
199
+ gapClass[gap],
200
+ !auto && columnsClass[columns],
201
+ className
202
+ ),
203
+ style: auto ? {
204
+ gridTemplateColumns: `repeat(auto-fill, minmax(${minColumnWidth}px, 1fr))`,
205
+ ...style
206
+ } : style,
207
+ ...props
208
+ }
209
+ );
210
+ }
211
+ function Section({
212
+ className,
213
+ heading,
214
+ description,
215
+ action,
216
+ gap = "sm",
217
+ children,
218
+ ...props
219
+ }) {
220
+ return /* @__PURE__ */ jsxs(
221
+ "section",
222
+ {
223
+ "data-slot": "section",
224
+ className: cn("flex flex-col", gapClass[gap], className),
225
+ ...props,
226
+ children: [
227
+ (heading || action) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
228
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
229
+ heading && /* @__PURE__ */ jsx2("h3", { className: "truncate text-[11px] font-semibold uppercase tracking-wider text-[var(--text-muted)]", children: heading }),
230
+ description && /* @__PURE__ */ jsx2("p", { className: "truncate text-xs text-[var(--text-muted)]", children: description })
231
+ ] }),
232
+ action && /* @__PURE__ */ jsx2("div", { className: "shrink-0", children: action })
233
+ ] }),
234
+ children
235
+ ]
236
+ }
237
+ );
238
+ }
239
+ var dividerSpacing = { none: "my-0", sm: "my-1", md: "my-2" };
240
+ function Divider({
241
+ className,
242
+ orientation = "horizontal",
243
+ spacing = "sm",
244
+ ...props
245
+ }) {
246
+ return /* @__PURE__ */ jsx2(
247
+ Separator,
248
+ {
249
+ "data-slot": "divider",
250
+ orientation,
251
+ className: cn(
252
+ orientation === "horizontal" ? dividerSpacing[spacing] : "mx-1",
253
+ className
254
+ ),
255
+ ...props
256
+ }
257
+ );
258
+ }
259
+
260
+ // src/components/dashboard/typography.tsx
261
+ import { cva as cva2 } from "class-variance-authority";
262
+ import { jsx as jsx3 } from "react/jsx-runtime";
263
+ var textVariants = cva2("min-w-0", {
264
+ variants: {
265
+ variant: {
266
+ body: "text-sm text-[var(--text-primary)]",
267
+ label: "text-[11px] font-semibold uppercase tracking-wider text-[var(--text-muted)]",
268
+ supporting: "text-xs text-[var(--text-secondary)]",
269
+ muted: "text-xs text-[var(--text-muted)]",
270
+ numeric: "text-sm font-semibold tabular-nums text-[var(--text-primary)]"
271
+ }
272
+ },
273
+ defaultVariants: { variant: "body" }
274
+ });
275
+ var clampClass = {
276
+ 1: "line-clamp-1",
277
+ 2: "line-clamp-2",
278
+ 3: "line-clamp-3"
279
+ };
280
+ function Text({
281
+ className,
282
+ variant,
283
+ truncate,
284
+ clamp,
285
+ tone,
286
+ ...props
287
+ }) {
288
+ return /* @__PURE__ */ jsx3(
289
+ "span",
290
+ {
291
+ "data-slot": "text",
292
+ className: cn(
293
+ textVariants({ variant }),
294
+ clamp ? clampClass[clamp] : truncate && "truncate",
295
+ tone && toneColor[tone],
296
+ className
297
+ ),
298
+ ...props
299
+ }
300
+ );
301
+ }
302
+ var headingSize = {
303
+ sm: "text-xs font-semibold",
304
+ md: "text-sm font-semibold",
305
+ lg: "text-base font-semibold"
306
+ };
307
+ function Heading({
308
+ className,
309
+ level = 2,
310
+ size = "md",
311
+ truncate,
312
+ ...props
313
+ }) {
314
+ const Tag = `h${level}`;
315
+ return /* @__PURE__ */ jsx3(
316
+ Tag,
317
+ {
318
+ "data-slot": "heading",
319
+ className: cn(
320
+ "leading-snug text-[var(--text-primary)]",
321
+ headingSize[size],
322
+ truncate && "truncate",
323
+ className
324
+ ),
325
+ ...props
326
+ }
327
+ );
328
+ }
329
+ var iconSize = {
330
+ xs: "size-3",
331
+ sm: "size-3.5",
332
+ md: "size-4",
333
+ lg: "size-5"
334
+ };
335
+ function Icon({ className, icon: IconCmp, size = "md", tone, label, ...props }) {
336
+ return /* @__PURE__ */ jsx3(
337
+ "span",
338
+ {
339
+ "data-slot": "icon",
340
+ role: label ? "img" : void 0,
341
+ "aria-label": label,
342
+ "aria-hidden": label ? void 0 : true,
343
+ className: cn(
344
+ "inline-flex shrink-0 items-center justify-center",
345
+ tone ? toneColor[tone] : "text-[var(--text-muted)]",
346
+ className
347
+ ),
348
+ ...props,
349
+ children: /* @__PURE__ */ jsx3(IconCmp, { className: iconSize[size] })
350
+ }
351
+ );
352
+ }
353
+
354
+ // src/components/dashboard/metric.tsx
355
+ import { ArrowDown, ArrowRight, ArrowUp } from "lucide-react";
356
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
357
+ var trendIcon = {
358
+ up: ArrowUp,
359
+ down: ArrowDown,
360
+ flat: ArrowRight
361
+ };
362
+ function Metric({
363
+ className,
364
+ label,
365
+ value,
366
+ icon,
367
+ supporting,
368
+ trend,
369
+ tone,
370
+ orientation = "vertical",
371
+ ...props
372
+ }) {
373
+ const TrendIcon = trend ? trendIcon[trend.direction] : null;
374
+ return /* @__PURE__ */ jsxs2(
375
+ "div",
376
+ {
377
+ "data-slot": "metric",
378
+ className: cn(
379
+ "flex min-w-0",
380
+ orientation === "vertical" ? "flex-col gap-0.5" : "items-center justify-between gap-2",
381
+ className
382
+ ),
383
+ ...props,
384
+ children: [
385
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5", children: [
386
+ icon && /* @__PURE__ */ jsx4(Icon, { icon, size: "sm" }),
387
+ /* @__PURE__ */ jsx4("span", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-[var(--text-muted)]", children: label })
388
+ ] }),
389
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-baseline gap-1.5", children: [
390
+ /* @__PURE__ */ jsx4(
391
+ "span",
392
+ {
393
+ className: cn(
394
+ "text-lg font-semibold leading-none tabular-nums",
395
+ tone ? toneColor[tone] : "text-[var(--text-primary)]"
396
+ ),
397
+ children: value
398
+ }
399
+ ),
400
+ trend && TrendIcon && /* @__PURE__ */ jsxs2(
401
+ "span",
402
+ {
403
+ className: cn(
404
+ "inline-flex items-center gap-0.5 text-xs font-medium tabular-nums",
405
+ trend.tone ? toneColor[trend.tone] : "text-[var(--text-muted)]"
406
+ ),
407
+ children: [
408
+ /* @__PURE__ */ jsx4(TrendIcon, { className: "size-3", "aria-hidden": true }),
409
+ trend.value
410
+ ]
411
+ }
412
+ )
413
+ ] }),
414
+ supporting && /* @__PURE__ */ jsx4("span", { className: "truncate text-xs text-[var(--text-muted)]", children: supporting })
415
+ ]
416
+ }
417
+ );
418
+ }
419
+ function MetricCard({ className, ...props }) {
420
+ return /* @__PURE__ */ jsx4(
421
+ "div",
422
+ {
423
+ "data-slot": "metric-card",
424
+ className: cn(
425
+ "flex min-w-0 flex-col rounded-lg border border-[var(--surface-line)] bg-[var(--surface-raised)] p-3 shadow-[inset_0_1px_0_var(--surface-rim)]",
426
+ className
427
+ ),
428
+ ...props
429
+ }
430
+ );
431
+ }
432
+ function MetricGroup({ columns = "auto", gap = "sm", minColumnWidth = 96, ...props }) {
433
+ return /* @__PURE__ */ jsx4(
434
+ Grid,
435
+ {
436
+ "data-slot": "metric-group",
437
+ columns,
438
+ gap,
439
+ minColumnWidth,
440
+ ...props
441
+ }
442
+ );
443
+ }
444
+
445
+ // src/components/dashboard/status.tsx
446
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
447
+ function Status({
448
+ className,
449
+ tone = "neutral",
450
+ variant = "dot",
451
+ pulse = false,
452
+ children,
453
+ ...props
454
+ }) {
455
+ const hasLabel = children != null && children !== "";
456
+ const hasAccessibleName = props["aria-label"] != null || props["aria-labelledby"] != null;
457
+ const hiddenLabel = !hasLabel && !hasAccessibleName ? /* @__PURE__ */ jsx5("span", { className: "sr-only", children: toneLabel[tone] }) : null;
458
+ if (variant === "pill") {
459
+ return /* @__PURE__ */ jsxs3(
460
+ "span",
461
+ {
462
+ "data-slot": "status",
463
+ "data-tone": tone,
464
+ className: cn(
465
+ "inline-flex w-fit items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium",
466
+ tonePill[tone],
467
+ className
468
+ ),
469
+ ...props,
470
+ children: [
471
+ /* @__PURE__ */ jsx5("span", { className: cn("size-1.5 shrink-0 rounded-full", toneDot[tone]) }),
472
+ children,
473
+ hiddenLabel
474
+ ]
475
+ }
476
+ );
477
+ }
478
+ return /* @__PURE__ */ jsxs3(
479
+ "span",
480
+ {
481
+ "data-slot": "status",
482
+ "data-tone": tone,
483
+ role: hasLabel ? void 0 : "status",
484
+ className: cn(
485
+ "inline-flex items-center gap-1.5 text-xs font-medium text-[var(--text-secondary)]",
486
+ className
487
+ ),
488
+ ...props,
489
+ children: [
490
+ /* @__PURE__ */ jsx5(
491
+ "span",
492
+ {
493
+ className: cn(
494
+ "size-2 shrink-0 rounded-full",
495
+ toneDot[tone],
496
+ // ring-current picks up the tone's text colour for a matching glow.
497
+ pulse && cn(toneColor[tone], "ring-2 ring-current/25")
498
+ )
499
+ }
500
+ ),
501
+ children,
502
+ hiddenLabel
503
+ ]
504
+ }
505
+ );
506
+ }
507
+
508
+ // src/components/dashboard/key-value.tsx
509
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
510
+ function KeyValue({ className, label, value, mono, ...props }) {
511
+ return /* @__PURE__ */ jsxs4(
512
+ "div",
513
+ {
514
+ "data-slot": "key-value",
515
+ className: cn("flex items-baseline justify-between gap-3", className),
516
+ ...props,
517
+ children: [
518
+ /* @__PURE__ */ jsx6("dt", { className: "shrink-0 truncate text-xs text-[var(--text-muted)]", children: label }),
519
+ /* @__PURE__ */ jsx6(
520
+ "dd",
521
+ {
522
+ className: cn(
523
+ "min-w-0 truncate text-right text-xs text-[var(--text-primary)]",
524
+ mono && "font-mono tabular-nums"
525
+ ),
526
+ children: value
527
+ }
528
+ )
529
+ ]
530
+ }
531
+ );
532
+ }
533
+ function KeyValueList({ className, ...props }) {
534
+ return /* @__PURE__ */ jsx6(
535
+ "dl",
536
+ {
537
+ "data-slot": "key-value-list",
538
+ className: cn("flex flex-col gap-1.5", className),
539
+ ...props
540
+ }
541
+ );
542
+ }
543
+
544
+ // src/components/ui/item.tsx
545
+ import { cva as cva3 } from "class-variance-authority";
546
+ import { Slot } from "radix-ui";
547
+ import { jsx as jsx7 } from "react/jsx-runtime";
548
+ var itemVariants = cva3(
549
+ "group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
550
+ {
551
+ variants: {
552
+ variant: {
553
+ default: "bg-transparent",
554
+ outline: "border-border",
555
+ muted: "bg-muted/50"
556
+ },
557
+ size: {
558
+ default: "p-4 gap-4 ",
559
+ sm: "py-3 px-4 gap-2.5"
560
+ }
561
+ },
562
+ defaultVariants: {
563
+ variant: "default",
564
+ size: "default"
565
+ }
566
+ }
567
+ );
568
+ function Item({
569
+ className,
570
+ variant = "default",
571
+ size = "default",
572
+ asChild = false,
573
+ ...props
574
+ }) {
575
+ const Comp = asChild ? Slot.Root : "div";
576
+ return /* @__PURE__ */ jsx7(
577
+ Comp,
578
+ {
579
+ "data-slot": "item",
580
+ "data-variant": variant,
581
+ "data-size": size,
582
+ className: cn(itemVariants({ variant, size, className })),
583
+ ...props
584
+ }
585
+ );
586
+ }
587
+ var itemMediaVariants = cva3(
588
+ "flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5",
589
+ {
590
+ variants: {
591
+ variant: {
592
+ default: "bg-transparent",
593
+ icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4",
594
+ image: "size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover"
595
+ }
596
+ },
597
+ defaultVariants: {
598
+ variant: "default"
599
+ }
600
+ }
601
+ );
602
+ function ItemMedia({
603
+ className,
604
+ variant = "default",
605
+ ...props
606
+ }) {
607
+ return /* @__PURE__ */ jsx7(
608
+ "div",
609
+ {
610
+ "data-slot": "item-media",
611
+ "data-variant": variant,
612
+ className: cn(itemMediaVariants({ variant, className })),
613
+ ...props
614
+ }
615
+ );
616
+ }
617
+ function ItemContent({ className, ...props }) {
618
+ return /* @__PURE__ */ jsx7(
619
+ "div",
620
+ {
621
+ "data-slot": "item-content",
622
+ className: cn(
623
+ "flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none",
624
+ className
625
+ ),
626
+ ...props
627
+ }
628
+ );
629
+ }
630
+ function ItemTitle({ className, ...props }) {
631
+ return /* @__PURE__ */ jsx7(
632
+ "div",
633
+ {
634
+ "data-slot": "item-title",
635
+ className: cn(
636
+ "flex w-fit items-center gap-2 text-sm leading-snug font-medium",
637
+ className
638
+ ),
639
+ ...props
640
+ }
641
+ );
642
+ }
643
+ function ItemDescription({ className, ...props }) {
644
+ return /* @__PURE__ */ jsx7(
645
+ "p",
646
+ {
647
+ "data-slot": "item-description",
648
+ className: cn(
649
+ "text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance",
650
+ "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
651
+ className
652
+ ),
653
+ ...props
654
+ }
655
+ );
656
+ }
657
+ function ItemActions({ className, ...props }) {
658
+ return /* @__PURE__ */ jsx7(
659
+ "div",
660
+ {
661
+ "data-slot": "item-actions",
662
+ className: cn("flex items-center gap-2", className),
663
+ ...props
664
+ }
665
+ );
666
+ }
667
+
668
+ // src/components/dashboard/item-list.tsx
669
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
670
+ function ItemListItem({
671
+ className,
672
+ leading,
673
+ primary,
674
+ secondary,
675
+ trailing,
676
+ actions,
677
+ variant = "default",
678
+ ...props
679
+ }) {
680
+ return /* @__PURE__ */ jsxs5(
681
+ Item,
682
+ {
683
+ "data-slot": "item-list-item",
684
+ variant,
685
+ size: "sm",
686
+ className: cn(
687
+ "gap-2 rounded-md bg-[var(--surface-flat)] p-2 transition-colors hover:bg-[var(--glass-hover)]",
688
+ className
689
+ ),
690
+ ...props,
691
+ children: [
692
+ leading && /* @__PURE__ */ jsx8(ItemMedia, { className: "self-center", children: leading }),
693
+ /* @__PURE__ */ jsxs5(ItemContent, { className: "gap-0.5", children: [
694
+ /* @__PURE__ */ jsx8(ItemTitle, { className: "truncate text-xs font-medium text-[var(--text-primary)]", children: primary }),
695
+ secondary && /* @__PURE__ */ jsx8(ItemDescription, { className: "line-clamp-1 text-xs text-[var(--text-muted)]", children: secondary })
696
+ ] }),
697
+ trailing && /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[11px] tabular-nums text-[var(--text-muted)]", children: trailing }),
698
+ actions && /* @__PURE__ */ jsx8(ItemActions, { children: actions })
699
+ ]
700
+ }
701
+ );
702
+ }
703
+ function ItemList({
704
+ className,
705
+ overflowCount = 0,
706
+ children,
707
+ ...props
708
+ }) {
709
+ return /* @__PURE__ */ jsxs5(
710
+ "div",
711
+ {
712
+ "data-slot": "item-list",
713
+ role: "list",
714
+ className: cn("flex min-w-0 flex-col gap-1", className),
715
+ ...props,
716
+ children: [
717
+ children,
718
+ overflowCount > 0 && /* @__PURE__ */ jsxs5("span", { className: "px-2 text-[11px] text-[var(--text-muted)]", children: [
719
+ "+",
720
+ overflowCount,
721
+ " more"
722
+ ] })
723
+ ]
724
+ }
725
+ );
726
+ }
727
+
728
+ // src/components/dashboard/activity-list.tsx
729
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
730
+ function ActivityListItem({
731
+ className,
732
+ label,
733
+ timestamp,
734
+ detail,
735
+ tone = "neutral",
736
+ icon,
737
+ ...props
738
+ }) {
739
+ return /* @__PURE__ */ jsxs6(
740
+ "li",
741
+ {
742
+ "data-slot": "activity-list-item",
743
+ className: cn("flex items-start gap-2 py-1", className),
744
+ ...props,
745
+ children: [
746
+ /* @__PURE__ */ jsx9("span", { className: "mt-1 flex size-3.5 shrink-0 items-center justify-center", children: icon ? /* @__PURE__ */ jsx9(Icon, { icon, size: "xs", tone: tone === "neutral" ? void 0 : tone }) : /* @__PURE__ */ jsx9("span", { className: cn("size-2 rounded-full", toneDot[tone]) }) }),
747
+ /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
748
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-baseline justify-between gap-2", children: [
749
+ /* @__PURE__ */ jsx9("span", { className: "truncate text-xs text-[var(--text-primary)]", children: label }),
750
+ timestamp && /* @__PURE__ */ jsx9("span", { className: "shrink-0 text-[11px] tabular-nums text-[var(--text-muted)]", children: timestamp })
751
+ ] }),
752
+ detail && /* @__PURE__ */ jsx9("span", { className: "line-clamp-1 text-xs text-[var(--text-muted)]", children: detail })
753
+ ] })
754
+ ]
755
+ }
756
+ );
757
+ }
758
+ function ActivityList({
759
+ className,
760
+ overflowCount = 0,
761
+ children,
762
+ ...props
763
+ }) {
764
+ return /* @__PURE__ */ jsxs6(
765
+ "ul",
766
+ {
767
+ "data-slot": "activity-list",
768
+ className: cn("flex min-w-0 flex-col", className),
769
+ ...props,
770
+ children: [
771
+ children,
772
+ overflowCount > 0 && /* @__PURE__ */ jsxs6("li", { className: "pl-5 pt-0.5 text-[11px] text-[var(--text-muted)]", children: [
773
+ "+",
774
+ overflowCount,
775
+ " more"
776
+ ] })
777
+ ]
778
+ }
779
+ );
780
+ }
781
+
782
+ // src/components/dashboard/progress-ring.tsx
783
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
784
+ function ProgressRing({
785
+ className,
786
+ value,
787
+ max = 100,
788
+ size = 44,
789
+ thickness = 4,
790
+ tone = "info",
791
+ label,
792
+ showValue = true,
793
+ children,
794
+ ...props
795
+ }) {
796
+ const clamped = Math.min(Math.max(value, 0), max);
797
+ const pct = max > 0 ? clamped / max : 0;
798
+ const radius = (size - thickness) / 2;
799
+ const circumference = 2 * Math.PI * radius;
800
+ const dashOffset = circumference * (1 - pct);
801
+ const center = size / 2;
802
+ return /* @__PURE__ */ jsxs7(
803
+ "div",
804
+ {
805
+ "data-slot": "progress-ring",
806
+ role: "progressbar",
807
+ "aria-label": label,
808
+ "aria-valuenow": Math.round(clamped),
809
+ "aria-valuemin": 0,
810
+ "aria-valuemax": max,
811
+ className: cn(
812
+ "relative inline-flex shrink-0 items-center justify-center",
813
+ toneColor[tone],
814
+ className
815
+ ),
816
+ style: { width: size, height: size },
817
+ ...props,
818
+ children: [
819
+ /* @__PURE__ */ jsxs7("svg", { width: size, height: size, className: "-rotate-90", children: [
820
+ /* @__PURE__ */ jsx10(
821
+ "circle",
822
+ {
823
+ cx: center,
824
+ cy: center,
825
+ r: radius,
826
+ fill: "none",
827
+ stroke: "var(--surface-line)",
828
+ strokeWidth: thickness
829
+ }
830
+ ),
831
+ /* @__PURE__ */ jsx10(
832
+ "circle",
833
+ {
834
+ cx: center,
835
+ cy: center,
836
+ r: radius,
837
+ fill: "none",
838
+ stroke: "currentColor",
839
+ strokeWidth: thickness,
840
+ strokeLinecap: "round",
841
+ strokeDasharray: circumference,
842
+ strokeDashoffset: dashOffset,
843
+ className: "transition-[stroke-dashoffset] duration-500"
844
+ }
845
+ )
846
+ ] }),
847
+ /* @__PURE__ */ jsx10("div", { className: "absolute inset-0 flex items-center justify-center text-[var(--text-primary)]", children: children ?? (showValue && /* @__PURE__ */ jsxs7("span", { className: "text-xs font-semibold tabular-nums", children: [
848
+ Math.round(pct * 100),
849
+ "%"
850
+ ] })) })
851
+ ]
852
+ }
853
+ );
854
+ }
855
+
856
+ // src/components/dashboard/stale-indicator.tsx
857
+ import { Clock, RotateCw } from "lucide-react";
858
+
859
+ // src/components/ui/button.tsx
860
+ import { cva as cva4 } from "class-variance-authority";
861
+ import { Slot as Slot2 } from "radix-ui";
862
+ import { jsx as jsx11 } from "react/jsx-runtime";
863
+ var buttonVariants = cva4(
864
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
865
+ {
866
+ variants: {
867
+ variant: {
868
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
869
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
870
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
871
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
872
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
873
+ link: "text-primary underline-offset-4 hover:underline"
874
+ },
875
+ size: {
876
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
877
+ xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
878
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
879
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
880
+ icon: "size-9",
881
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
882
+ "icon-sm": "size-8",
883
+ "icon-lg": "size-10"
884
+ }
885
+ },
886
+ defaultVariants: {
887
+ variant: "default",
888
+ size: "default"
889
+ }
890
+ }
891
+ );
892
+ function Button({
893
+ className,
894
+ variant = "default",
895
+ size = "default",
896
+ asChild = false,
897
+ ...props
898
+ }) {
899
+ const Comp = asChild ? Slot2.Root : "button";
900
+ return /* @__PURE__ */ jsx11(
901
+ Comp,
902
+ {
903
+ "data-slot": "button",
904
+ "data-variant": variant,
905
+ "data-size": size,
906
+ className: cn(buttonVariants({ variant, size, className })),
907
+ ...props
908
+ }
909
+ );
910
+ }
911
+
912
+ // src/components/dashboard/icon-button.tsx
913
+ import { jsx as jsx12 } from "react/jsx-runtime";
914
+ var sizeMap = {
915
+ xs: "icon-xs",
916
+ sm: "icon-sm",
917
+ md: "icon"
918
+ };
919
+ var iconSizeMap = {
920
+ xs: "xs",
921
+ sm: "sm",
922
+ md: "md"
923
+ };
924
+ function IconButton({
925
+ className,
926
+ icon,
927
+ label,
928
+ size = "sm",
929
+ variant = "ghost",
930
+ ...props
931
+ }) {
932
+ return /* @__PURE__ */ jsx12(
933
+ Button,
934
+ {
935
+ "data-slot": "icon-button",
936
+ type: "button",
937
+ variant,
938
+ size: sizeMap[size],
939
+ "aria-label": label,
940
+ title: label,
941
+ className: cn("text-[var(--text-muted)]", className),
942
+ ...props,
943
+ children: /* @__PURE__ */ jsx12(Icon, { icon, size: iconSizeMap[size], className: "text-current" })
944
+ }
945
+ );
946
+ }
947
+
948
+ // src/components/dashboard/stale-indicator.tsx
949
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
950
+ function StaleIndicator({
951
+ className,
952
+ lastUpdated,
953
+ onRefresh,
954
+ refreshing = false,
955
+ ...props
956
+ }) {
957
+ return /* @__PURE__ */ jsxs8(
958
+ "div",
959
+ {
960
+ "data-slot": "stale-indicator",
961
+ className: cn(
962
+ "flex items-center gap-1.5 text-[11px] text-[var(--text-muted)]",
963
+ className
964
+ ),
965
+ ...props,
966
+ children: [
967
+ /* @__PURE__ */ jsx13(Icon, { icon: Clock, size: "xs", tone: "warning" }),
968
+ /* @__PURE__ */ jsx13("span", { className: "truncate", children: lastUpdated ?? "Data may be out of date" }),
969
+ onRefresh && /* @__PURE__ */ jsx13(
970
+ IconButton,
971
+ {
972
+ icon: RotateCw,
973
+ label: "Refresh",
974
+ size: "xs",
975
+ onClick: onRefresh,
976
+ className: cn("ml-auto", refreshing && "animate-spin"),
977
+ disabled: refreshing
978
+ }
979
+ )
980
+ ]
981
+ }
982
+ );
983
+ }
984
+
985
+ // src/components/dashboard/data-boundary.tsx
986
+ import { Fragment, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
987
+ function DataBoundary({
988
+ state,
989
+ loading,
990
+ empty,
991
+ error,
992
+ stale,
993
+ children
994
+ }) {
995
+ switch (state) {
996
+ case "loading":
997
+ return /* @__PURE__ */ jsx14(Fragment, { children: loading ?? null });
998
+ case "empty":
999
+ return /* @__PURE__ */ jsx14(Fragment, { children: empty ?? null });
1000
+ case "error":
1001
+ return /* @__PURE__ */ jsx14(Fragment, { children: error ?? null });
1002
+ case "stale":
1003
+ return /* @__PURE__ */ jsxs9(Fragment, { children: [
1004
+ stale,
1005
+ children
1006
+ ] });
1007
+ case "ready":
1008
+ default:
1009
+ return /* @__PURE__ */ jsx14(Fragment, { children });
1010
+ }
1011
+ }
1012
+
1013
+ // src/components/ui/empty.tsx
1014
+ import { cva as cva5 } from "class-variance-authority";
1015
+ import { jsx as jsx15 } from "react/jsx-runtime";
1016
+ var emptyMediaVariants = cva5(
1017
+ "flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0",
1018
+ {
1019
+ variants: {
1020
+ variant: {
1021
+ default: "bg-transparent",
1022
+ icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6"
1023
+ }
1024
+ },
1025
+ defaultVariants: {
1026
+ variant: "default"
1027
+ }
1028
+ }
1029
+ );
1030
+
1031
+ // src/components/dashboard/empty-state.tsx
1032
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
1033
+
1034
+ // src/components/ui/skeleton.tsx
1035
+ import { jsx as jsx17 } from "react/jsx-runtime";
1036
+
1037
+ // src/components/dashboard/skeletons.tsx
1038
+ import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
1039
+
1040
+ // src/components/reference/StarterExample.tsx
1041
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1042
+ var RECENT = [
1043
+ { id: "a", label: "Nightly build", timestamp: "12m", tone: "success" },
1044
+ { id: "b", label: "Deploy to staging", timestamp: "1h", tone: "info" },
1045
+ { id: "c", label: "Dependency audit", timestamp: "3h", tone: "neutral" }
1046
+ ];
1047
+ function StarterExample() {
1048
+ return /* @__PURE__ */ jsx19(WidgetContent, { children: /* @__PURE__ */ jsxs12(Stack, { gap: "sm", children: [
1049
+ /* @__PURE__ */ jsx19(Metric, { label: "Tasks done", value: 12, icon: CheckCircle2, tone: "success" }),
1050
+ /* @__PURE__ */ jsx19(Section, { heading: "Recent", children: /* @__PURE__ */ jsx19(ActivityList, { children: RECENT.map((e) => /* @__PURE__ */ jsx19(
1051
+ ActivityListItem,
1052
+ {
1053
+ tone: e.tone,
1054
+ label: e.label,
1055
+ timestamp: e.timestamp
1056
+ },
1057
+ e.id
1058
+ )) }) })
1059
+ ] }) });
1060
+ }
1061
+
1062
+ // src/components/reference/SchedulerExample.tsx
1063
+ import { ExternalLink } from "lucide-react";
1064
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1065
+ var UPCOMING = [
1066
+ { id: "a", label: "Daily backup", timestamp: "08:00", tone: "success" },
1067
+ { id: "b", label: "Publish report", timestamp: "in 2h", tone: "info" },
1068
+ { id: "c", label: "Rotate API keys", timestamp: "tomorrow", tone: "warning" }
1069
+ ];
1070
+ function SchedulerExample() {
1071
+ return /* @__PURE__ */ jsx20(WidgetContent, { children: /* @__PURE__ */ jsxs13(Stack, { gap: "sm", children: [
1072
+ /* @__PURE__ */ jsxs13(Inline, { justify: "between", align: "center", children: [
1073
+ /* @__PURE__ */ jsx20(Status, { tone: "success", pulse: true, children: "Scheduler active" }),
1074
+ /* @__PURE__ */ jsx20(ProgressRing, { value: 92, label: "Success rate", tone: "success", size: 40 })
1075
+ ] }),
1076
+ /* @__PURE__ */ jsx20(Section, { heading: "Summary", children: /* @__PURE__ */ jsxs13(Inline, { gap: "sm", wrap: true, children: [
1077
+ /* @__PURE__ */ jsx20(MetricCard, { className: "flex-1", children: /* @__PURE__ */ jsx20(Metric, { label: "Jobs", value: 6 }) }),
1078
+ /* @__PURE__ */ jsx20(MetricCard, { className: "flex-1", children: /* @__PURE__ */ jsx20(
1079
+ Metric,
1080
+ {
1081
+ label: "Runs today",
1082
+ value: 18,
1083
+ trend: { direction: "up", value: "+4", tone: "success" }
1084
+ }
1085
+ ) })
1086
+ ] }) }),
1087
+ /* @__PURE__ */ jsx20(Divider, {}),
1088
+ /* @__PURE__ */ jsx20(
1089
+ Section,
1090
+ {
1091
+ heading: "Next up",
1092
+ action: /* @__PURE__ */ jsxs13(Button, { size: "xs", variant: "ghost", children: [
1093
+ /* @__PURE__ */ jsx20(ExternalLink, { className: "size-3" }),
1094
+ "All"
1095
+ ] }),
1096
+ children: /* @__PURE__ */ jsx20(DataBoundary, { state: "ready", children: /* @__PURE__ */ jsx20(ActivityList, { children: UPCOMING.map((e) => /* @__PURE__ */ jsx20(
1097
+ ActivityListItem,
1098
+ {
1099
+ tone: e.tone,
1100
+ label: e.label,
1101
+ timestamp: e.timestamp
1102
+ },
1103
+ e.id
1104
+ )) }) })
1105
+ }
1106
+ ),
1107
+ /* @__PURE__ */ jsx20(StaleIndicator, { lastUpdated: "Updated 2m ago" })
1108
+ ] }) });
1109
+ }
1110
+
1111
+ // src/components/reference/ResourceExample.tsx
1112
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1113
+ function Ring({
1114
+ value,
1115
+ label,
1116
+ tone
1117
+ }) {
1118
+ return /* @__PURE__ */ jsxs14(Stack, { gap: "xs", align: "center", children: [
1119
+ /* @__PURE__ */ jsx21(ProgressRing, { value, label, tone }),
1120
+ /* @__PURE__ */ jsx21(Text, { variant: "muted", children: label })
1121
+ ] });
1122
+ }
1123
+ function ResourceExample() {
1124
+ return /* @__PURE__ */ jsx21(WidgetContent, { scroll: true, children: /* @__PURE__ */ jsxs14(Stack, { gap: "sm", children: [
1125
+ /* @__PURE__ */ jsx21(Heading, { level: 2, size: "md", children: "Resources" }),
1126
+ /* @__PURE__ */ jsxs14(MetricGroup, { children: [
1127
+ /* @__PURE__ */ jsx21(Metric, { label: "CPU", value: "42%", tone: "success" }),
1128
+ /* @__PURE__ */ jsx21(Metric, { label: "Memory", value: "6.1 GB" }),
1129
+ /* @__PURE__ */ jsx21(Metric, { label: "Disk", value: "71%", tone: "warning" })
1130
+ ] }),
1131
+ /* @__PURE__ */ jsx21(Divider, {}),
1132
+ /* @__PURE__ */ jsx21(Section, { heading: "Usage", children: /* @__PURE__ */ jsxs14(Grid, { columns: 3, gap: "sm", children: [
1133
+ /* @__PURE__ */ jsx21(Ring, { value: 42, label: "CPU", tone: "success" }),
1134
+ /* @__PURE__ */ jsx21(Ring, { value: 61, label: "Memory", tone: "info" }),
1135
+ /* @__PURE__ */ jsx21(Ring, { value: 71, label: "Disk", tone: "warning" })
1136
+ ] }) }),
1137
+ /* @__PURE__ */ jsx21(Divider, {}),
1138
+ /* @__PURE__ */ jsx21(Section, { heading: "Host", children: /* @__PURE__ */ jsxs14(KeyValueList, { children: [
1139
+ /* @__PURE__ */ jsx21(KeyValue, { label: "Region", value: "eu-west-1", mono: true }),
1140
+ /* @__PURE__ */ jsx21(KeyValue, { label: "Instance", value: "c7g.xlarge", mono: true }),
1141
+ /* @__PURE__ */ jsx21(KeyValue, { label: "Uptime", value: "14d 6h", mono: true }),
1142
+ /* @__PURE__ */ jsx21(KeyValue, { label: "Status", value: /* @__PURE__ */ jsx21(Status, { tone: "success", children: "Healthy" }) })
1143
+ ] }) })
1144
+ ] }) });
1145
+ }
1146
+
1147
+ // src/components/reference/ActivityExample.tsx
1148
+ import { FileText } from "lucide-react";
1149
+
1150
+ // src/components/ui/badge.tsx
1151
+ import { cva as cva6 } from "class-variance-authority";
1152
+ import { Slot as Slot3 } from "radix-ui";
1153
+ import { jsx as jsx22 } from "react/jsx-runtime";
1154
+ var badgeVariants = cva6(
1155
+ "inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
1156
+ {
1157
+ variants: {
1158
+ variant: {
1159
+ default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
1160
+ secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
1161
+ destructive: "bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
1162
+ outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
1163
+ ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
1164
+ link: "text-primary underline-offset-4 [a&]:hover:underline",
1165
+ // Semantic status tones (error is covered by `destructive`).
1166
+ success: "bg-[var(--status-success-muted)] text-[var(--status-success)]",
1167
+ warning: "bg-[var(--status-warning-muted)] text-[var(--status-warning)]",
1168
+ info: "bg-[var(--status-info-muted)] text-[var(--status-info)]"
1169
+ }
1170
+ },
1171
+ defaultVariants: {
1172
+ variant: "default"
1173
+ }
1174
+ }
1175
+ );
1176
+ function Badge({
1177
+ className,
1178
+ variant = "default",
1179
+ asChild = false,
1180
+ ...props
1181
+ }) {
1182
+ const Comp = asChild ? Slot3.Root : "span";
1183
+ return /* @__PURE__ */ jsx22(
1184
+ Comp,
1185
+ {
1186
+ "data-slot": "badge",
1187
+ "data-variant": variant,
1188
+ className: cn(badgeVariants({ variant }), className),
1189
+ ...props
1190
+ }
1191
+ );
1192
+ }
1193
+
1194
+ // src/components/reference/ActivityExample.tsx
1195
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
1196
+ var ITEMS = [
1197
+ { id: "1", title: "quarterly-report.pdf", meta: "2h", badge: "PDF" },
1198
+ { id: "2", title: "design-tokens.json", meta: "5h", badge: "JSON" },
1199
+ { id: "3", title: "release-notes.md", meta: "1d", badge: "MD" }
1200
+ ];
1201
+ function ActivityExample() {
1202
+ return /* @__PURE__ */ jsx23(WidgetContent, { children: /* @__PURE__ */ jsxs15(Stack, { gap: "sm", fill: true, children: [
1203
+ /* @__PURE__ */ jsx23(Inline, { justify: "between", align: "center", children: /* @__PURE__ */ jsxs15(Inline, { gap: "xs", align: "center", children: [
1204
+ /* @__PURE__ */ jsx23(Text, { variant: "label", children: "Recent files" }),
1205
+ /* @__PURE__ */ jsx23(Badge, { variant: "info", children: ITEMS.length })
1206
+ ] }) }),
1207
+ /* @__PURE__ */ jsx23(Stack, { gap: "none", scroll: true, children: /* @__PURE__ */ jsx23(ItemList, { children: ITEMS.map((f) => /* @__PURE__ */ jsx23(
1208
+ ItemListItem,
1209
+ {
1210
+ leading: /* @__PURE__ */ jsx23(FileText, { className: "size-4 text-[var(--text-muted)]" }),
1211
+ primary: f.title,
1212
+ trailing: /* @__PURE__ */ jsxs15(Inline, { gap: "xs", align: "center", children: [
1213
+ /* @__PURE__ */ jsx23(Badge, { variant: "secondary", children: f.badge }),
1214
+ /* @__PURE__ */ jsx23("span", { children: f.meta })
1215
+ ] })
1216
+ },
1217
+ f.id
1218
+ )) }) }),
1219
+ /* @__PURE__ */ jsxs15(Inline, { justify: "between", align: "center", children: [
1220
+ /* @__PURE__ */ jsx23(Status, { tone: "info", variant: "pill", children: "Synced" }),
1221
+ /* @__PURE__ */ jsx23(StaleIndicator, { lastUpdated: "Synced 30s ago" })
1222
+ ] })
1223
+ ] }) });
1224
+ }
1225
+ export {
1226
+ ActivityExample,
1227
+ ResourceExample,
1228
+ SchedulerExample,
1229
+ StarterExample
1230
+ };