@khal-os/ui 1.0.0 → 1.0.2

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 (59) hide show
  1. package/LICENSE +94 -0
  2. package/README.md +25 -0
  3. package/dist/index.cjs +2661 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +926 -0
  6. package/dist/index.d.ts +926 -0
  7. package/dist/index.js +2510 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +59 -40
  10. package/tokens.css +260 -238
  11. package/src/components/ContextMenu.tsx +0 -130
  12. package/src/components/avatar.tsx +0 -71
  13. package/src/components/badge.tsx +0 -39
  14. package/src/components/button.tsx +0 -102
  15. package/src/components/command.tsx +0 -165
  16. package/src/components/cost-counter.tsx +0 -75
  17. package/src/components/data-row.tsx +0 -97
  18. package/src/components/dropdown-menu.tsx +0 -233
  19. package/src/components/glass-card.tsx +0 -74
  20. package/src/components/input.tsx +0 -48
  21. package/src/components/khal-logo.tsx +0 -73
  22. package/src/components/live-feed.tsx +0 -109
  23. package/src/components/mesh-gradient.tsx +0 -57
  24. package/src/components/metric-display.tsx +0 -93
  25. package/src/components/note.tsx +0 -55
  26. package/src/components/number-flow.tsx +0 -25
  27. package/src/components/pill-badge.tsx +0 -65
  28. package/src/components/progress-bar.tsx +0 -70
  29. package/src/components/section-card.tsx +0 -76
  30. package/src/components/separator.tsx +0 -25
  31. package/src/components/spinner.tsx +0 -42
  32. package/src/components/status-dot.tsx +0 -90
  33. package/src/components/switch.tsx +0 -36
  34. package/src/components/theme-provider.tsx +0 -58
  35. package/src/components/theme-switcher.tsx +0 -59
  36. package/src/components/ticker-bar.tsx +0 -41
  37. package/src/components/tooltip.tsx +0 -62
  38. package/src/components/window-minimized-context.tsx +0 -29
  39. package/src/hooks/useReducedMotion.ts +0 -21
  40. package/src/index.ts +0 -58
  41. package/src/lib/animations.ts +0 -50
  42. package/src/primitives/collapsible-sidebar.tsx +0 -226
  43. package/src/primitives/dialog.tsx +0 -76
  44. package/src/primitives/empty-state.tsx +0 -43
  45. package/src/primitives/index.ts +0 -22
  46. package/src/primitives/list-view.tsx +0 -155
  47. package/src/primitives/property-panel.tsx +0 -108
  48. package/src/primitives/section-header.tsx +0 -19
  49. package/src/primitives/sidebar-nav.tsx +0 -110
  50. package/src/primitives/split-pane.tsx +0 -146
  51. package/src/primitives/status-badge.tsx +0 -10
  52. package/src/primitives/status-bar.tsx +0 -100
  53. package/src/primitives/toolbar.tsx +0 -152
  54. package/src/server.ts +0 -4
  55. package/src/stores/notification-store.ts +0 -271
  56. package/src/stores/theme-store.ts +0 -33
  57. package/src/tokens/lp-tokens.ts +0 -36
  58. package/src/utils.ts +0 -6
  59. package/tsconfig.json +0 -17
package/dist/index.cjs ADDED
@@ -0,0 +1,2661 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ ACCENT_BLUE: () => ACCENT_BLUE,
34
+ Avatar: () => Avatar,
35
+ BUTTON_RADIUS: () => BUTTON_RADIUS,
36
+ Badge: () => Badge,
37
+ Button: () => Button,
38
+ CELL_BG: () => CELL_BG,
39
+ CHROME_BG: () => CHROME_BG,
40
+ CollapsibleSidebar: () => CollapsibleSidebar,
41
+ Command: () => Command,
42
+ CommandDialog: () => CommandDialog,
43
+ CommandEmpty: () => CommandEmpty,
44
+ CommandGroup: () => CommandGroup,
45
+ CommandInput: () => CommandInput,
46
+ CommandItem: () => CommandItem,
47
+ CommandList: () => CommandList,
48
+ CommandSeparator: () => CommandSeparator,
49
+ CommandShortcut: () => CommandShortcut,
50
+ ContextMenu: () => ContextMenu,
51
+ ContextMenuContent: () => ContextMenuContent,
52
+ ContextMenuGroup: () => ContextMenuGroup,
53
+ ContextMenuItem: () => ContextMenuItem,
54
+ ContextMenuPortal: () => ContextMenuPortal,
55
+ ContextMenuRadioGroup: () => ContextMenuRadioGroup,
56
+ ContextMenuSeparator: () => ContextMenuSeparator,
57
+ ContextMenuSub: () => ContextMenuSub,
58
+ ContextMenuSubContent: () => ContextMenuSubContent,
59
+ ContextMenuSubTrigger: () => ContextMenuSubTrigger,
60
+ ContextMenuTrigger: () => ContextMenuTrigger,
61
+ CostCounter: () => CostCounter,
62
+ DataRow: () => DataRow,
63
+ Dialog: () => Dialog,
64
+ DropdownMenu: () => DropdownMenu,
65
+ DropdownMenuCheckboxItem: () => DropdownMenuCheckboxItem,
66
+ DropdownMenuContent: () => DropdownMenuContent,
67
+ DropdownMenuGroup: () => DropdownMenuGroup,
68
+ DropdownMenuItem: () => DropdownMenuItem,
69
+ DropdownMenuLabel: () => DropdownMenuLabel,
70
+ DropdownMenuPortal: () => DropdownMenuPortal,
71
+ DropdownMenuRadioGroup: () => DropdownMenuRadioGroup,
72
+ DropdownMenuRadioItem: () => DropdownMenuRadioItem,
73
+ DropdownMenuSeparator: () => DropdownMenuSeparator,
74
+ DropdownMenuShortcut: () => DropdownMenuShortcut,
75
+ DropdownMenuSub: () => DropdownMenuSub,
76
+ DropdownMenuSubContent: () => DropdownMenuSubContent,
77
+ DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
78
+ DropdownMenuTrigger: () => DropdownMenuTrigger,
79
+ EmptyState: () => EmptyState,
80
+ GlassCard: () => GlassCard,
81
+ Input: () => Input,
82
+ KhalLogo: () => KhalLogo,
83
+ ListView: () => ListView,
84
+ LiveFeed: () => LiveFeed,
85
+ MESH_GRADIENT_PALETTE: () => MESH_GRADIENT_PALETTE,
86
+ MeshGradient: () => MeshGradientInner,
87
+ MetricDisplay: () => MetricDisplay,
88
+ Note: () => Note,
89
+ NumberFlow: () => NumberFlow,
90
+ PillBadge: () => PillBadge,
91
+ ProgressBar: () => ProgressBar,
92
+ PropertyPanel: () => PropertyPanel,
93
+ SUBJECTS: () => import_app.SUBJECTS,
94
+ SectionCard: () => SectionCard,
95
+ SectionCardHeader: () => SectionCardHeader,
96
+ SectionHeader: () => SectionHeader,
97
+ Separator: () => Separator3,
98
+ SidebarNav: () => SidebarNav,
99
+ Spinner: () => Spinner,
100
+ SplitPane: () => SplitPane,
101
+ StatusBadge: () => StatusBadge,
102
+ StatusBar: () => StatusBar,
103
+ StatusDot: () => StatusDot,
104
+ TEXT_PRIMARY: () => TEXT_PRIMARY,
105
+ TEXT_SECONDARY: () => TEXT_SECONDARY,
106
+ TEXT_TERTIARY: () => TEXT_TERTIARY,
107
+ ThemeProvider: () => ThemeProvider,
108
+ ThemeSwitcher: () => ThemeSwitcher,
109
+ TickerBar: () => TickerBar,
110
+ Toggle: () => Toggle,
111
+ Toolbar: () => Toolbar,
112
+ Tooltip: () => Tooltip,
113
+ TooltipContent: () => TooltipContent,
114
+ TooltipProvider: () => TooltipProvider,
115
+ TooltipRoot: () => TooltipRoot,
116
+ TooltipTrigger: () => TooltipTrigger,
117
+ WINDOW_RADIUS: () => WINDOW_RADIUS,
118
+ WIN_BG: () => WIN_BG,
119
+ WIN_BORDER: () => WIN_BORDER,
120
+ WIN_BORDER_FOCUSED: () => WIN_BORDER_FOCUSED,
121
+ WindowActiveProvider: () => WindowActiveProvider,
122
+ WindowMinimizedProvider: () => WindowMinimizedProvider,
123
+ badgeVariants: () => badgeVariants,
124
+ buttonVariants: () => buttonVariants,
125
+ cn: () => cn,
126
+ dataRowVariants: () => dataRowVariants,
127
+ fadeIn: () => fadeIn,
128
+ fadeUp: () => fadeUp,
129
+ glassCardVariants: () => glassCardVariants,
130
+ khalEasing: () => khalEasing,
131
+ metricDisplayVariants: () => metricDisplayVariants,
132
+ pillBadgeVariants: () => pillBadgeVariants,
133
+ progressBarVariants: () => progressBarVariants,
134
+ scaleUp: () => scaleUp,
135
+ sectionCardVariants: () => sectionCardVariants,
136
+ springConfig: () => springConfig,
137
+ staggerChild: () => staggerChild,
138
+ staggerContainer: () => staggerContainer,
139
+ stateConfig: () => stateConfig,
140
+ useKhalAuth: () => import_app.useKhalAuth,
141
+ useNats: () => import_app.useNats,
142
+ useNatsSubscription: () => import_app.useNatsSubscription,
143
+ useNotificationStore: () => useNotificationStore,
144
+ useOSAuth: () => import_app.useKhalAuth,
145
+ useReducedMotion: () => useReducedMotion,
146
+ useSidebar: () => useSidebar,
147
+ useThemeStore: () => useThemeStore,
148
+ useWindowActive: () => useWindowActive,
149
+ useWindowMinimized: () => useWindowMinimized
150
+ });
151
+ module.exports = __toCommonJS(index_exports);
152
+ var import_app = require("@khal-os/sdk/app");
153
+
154
+ // src/components/avatar.tsx
155
+ var React = __toESM(require("react"), 1);
156
+
157
+ // src/utils.ts
158
+ var import_clsx = require("clsx");
159
+ var import_tailwind_merge = require("tailwind-merge");
160
+ function cn(...inputs) {
161
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
162
+ }
163
+
164
+ // src/components/status-dot.tsx
165
+ var import_jsx_runtime = require("react/jsx-runtime");
166
+ var sizeMap = { sm: 8, md: 10, lg: 12 };
167
+ var stateConfig = {
168
+ live: { color: "#22c55e", label: "Live", pulse: true },
169
+ online: { color: "#22c55e", label: "Online", pulse: false },
170
+ active: { color: "#22c55e", label: "Active", pulse: true },
171
+ working: { color: "#f59e0b", label: "Working", pulse: true },
172
+ idle: { color: "#64748b", label: "Idle", pulse: false },
173
+ away: { color: "#64748b", label: "Away", pulse: false },
174
+ queued: { color: "#f59e0b", label: "Queued", pulse: false },
175
+ error: { color: "#ef4444", label: "Error", pulse: true }
176
+ };
177
+ function StatusDot({
178
+ state,
179
+ color: colorProp,
180
+ pulse: pulseProp,
181
+ size = "md",
182
+ label: labelProp,
183
+ showLabel = false,
184
+ className,
185
+ style,
186
+ ...props
187
+ }) {
188
+ const config = state ? stateConfig[state] : null;
189
+ const color = colorProp ?? config?.color ?? "#64748b";
190
+ const pulse = pulseProp ?? config?.pulse ?? false;
191
+ const label = labelProp ?? config?.label;
192
+ const px = sizeMap[size];
193
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
194
+ "span",
195
+ {
196
+ role: "status",
197
+ "aria-label": label,
198
+ className: cn("relative inline-flex shrink-0 items-center gap-1.5", className),
199
+ style,
200
+ ...props,
201
+ children: [
202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "relative inline-flex shrink-0", style: { width: px, height: px }, children: [
203
+ pulse && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
204
+ "span",
205
+ {
206
+ className: "absolute -inset-0.5 rounded-full",
207
+ style: {
208
+ backgroundColor: color,
209
+ opacity: 0.35,
210
+ animation: "khal-pulse 2s ease-in-out infinite"
211
+ }
212
+ }
213
+ ),
214
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
215
+ "span",
216
+ {
217
+ className: "absolute inset-0 rounded-full",
218
+ style: {
219
+ backgroundColor: color,
220
+ boxShadow: pulse ? `0 0 ${px}px ${color}80` : void 0
221
+ }
222
+ }
223
+ )
224
+ ] }),
225
+ showLabel && label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[11px] leading-none", style: { color }, children: label })
226
+ ]
227
+ }
228
+ );
229
+ }
230
+
231
+ // src/components/avatar.tsx
232
+ var import_jsx_runtime2 = require("react/jsx-runtime");
233
+ var sizeMap2 = { sm: 24, md: 32, lg: 40 };
234
+ var fontSizeMap = { sm: "10px", md: "12px", lg: "14px" };
235
+ var statusColorMap = {
236
+ online: "var(--khal-status-live)",
237
+ idle: "var(--khal-status-warning)",
238
+ away: "var(--khal-status-idle)"
239
+ };
240
+ function getInitials(name) {
241
+ const parts = name.trim().split(/\s+/);
242
+ if (parts.length >= 2) {
243
+ return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
244
+ }
245
+ return name.charAt(0).toUpperCase();
246
+ }
247
+ var Avatar = React.forwardRef(
248
+ ({ name, size = "md", status, src, className, style, ...props }, ref) => {
249
+ const px = sizeMap2[size];
250
+ const [imgError, setImgError] = React.useState(false);
251
+ const showImage = src && !imgError;
252
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
253
+ "div",
254
+ {
255
+ ref,
256
+ className: cn("relative inline-flex shrink-0", className),
257
+ style: { width: px, height: px, ...style },
258
+ ...props,
259
+ children: [
260
+ showImage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
261
+ "img",
262
+ {
263
+ src,
264
+ alt: name,
265
+ className: "h-full w-full rounded-full object-cover",
266
+ onError: () => setImgError(true)
267
+ }
268
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
269
+ "div",
270
+ {
271
+ className: "flex h-full w-full select-none items-center justify-center rounded-full border font-medium [background:var(--khal-surface-raised)] [border-color:var(--khal-border-subtle)]",
272
+ style: { fontSize: fontSizeMap[size] },
273
+ children: getInitials(name)
274
+ }
275
+ ),
276
+ status && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute -bottom-px -right-px", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StatusDot, { color: statusColorMap[status], size: "sm", label: status, pulse: status === "online" }) })
277
+ ]
278
+ }
279
+ );
280
+ }
281
+ );
282
+ Avatar.displayName = "Avatar";
283
+
284
+ // src/components/badge.tsx
285
+ var import_class_variance_authority = require("class-variance-authority");
286
+ var import_jsx_runtime3 = require("react/jsx-runtime");
287
+ var badgeVariants = (0, import_class_variance_authority.cva)(
288
+ "inline-flex items-center rounded-full border font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-blue-700 focus:ring-offset-2",
289
+ {
290
+ variants: {
291
+ variant: {
292
+ gray: "border-gray-alpha-400 bg-gray-100 text-gray-900",
293
+ blue: "border-blue-300 bg-blue-100 text-blue-900",
294
+ green: "border-green-300 bg-green-100 text-green-900",
295
+ amber: "border-amber-300 bg-amber-100 text-amber-900",
296
+ red: "border-red-300 bg-red-100 text-red-900",
297
+ purple: "border-purple-300 bg-purple-100 text-purple-900",
298
+ pink: "border-pink-300 bg-pink-100 text-pink-900",
299
+ teal: "border-teal-300 bg-teal-100 text-teal-900"
300
+ },
301
+ size: {
302
+ sm: "px-2 py-0 text-[11px] leading-[18px]",
303
+ md: "px-2.5 py-0.5 text-[12px] leading-[18px]"
304
+ }
305
+ },
306
+ defaultVariants: {
307
+ variant: "gray",
308
+ size: "md"
309
+ }
310
+ }
311
+ );
312
+ function Badge({ className, variant, size, contrast, ...props }) {
313
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cn(badgeVariants({ variant, size }), className), ...props });
314
+ }
315
+
316
+ // src/components/button.tsx
317
+ var import_react_slot = require("@radix-ui/react-slot");
318
+ var import_class_variance_authority2 = require("class-variance-authority");
319
+ var React2 = __toESM(require("react"), 1);
320
+
321
+ // src/components/spinner.tsx
322
+ var import_jsx_runtime4 = require("react/jsx-runtime");
323
+ var sizeMap3 = {
324
+ sm: 16,
325
+ md: 20,
326
+ lg: 24
327
+ };
328
+ function Spinner({ size = "md", className, ...props }) {
329
+ const px = sizeMap3[size];
330
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
331
+ "div",
332
+ {
333
+ role: "status",
334
+ "aria-label": "Loading",
335
+ className: cn("inline-flex items-center justify-center", className),
336
+ ...props,
337
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: px, height: px, viewBox: "0 0 20 20", fill: "none", className: "animate-spin", children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "10", cy: "10", r: "8", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", opacity: "0.25" }),
339
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
340
+ "circle",
341
+ {
342
+ cx: "10",
343
+ cy: "10",
344
+ r: "8",
345
+ stroke: "currentColor",
346
+ strokeWidth: "2",
347
+ strokeLinecap: "round",
348
+ strokeDasharray: "50.26",
349
+ strokeDashoffset: "37.7"
350
+ }
351
+ )
352
+ ] })
353
+ }
354
+ );
355
+ }
356
+
357
+ // src/components/button.tsx
358
+ var import_jsx_runtime5 = require("react/jsx-runtime");
359
+ var buttonVariants = (0, import_class_variance_authority2.cva)(
360
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[var(--khal-radius-button,10px)] text-copy-13 font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--khal-accent-primary)] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 cursor-pointer",
361
+ {
362
+ variants: {
363
+ variant: {
364
+ default: "bg-gray-1000 text-white [color:white] dark:text-black dark:[color:black] hover:bg-gray-900",
365
+ secondary: "bg-background-100 text-gray-1000 border border-gray-alpha-400 hover:bg-gray-alpha-100",
366
+ tertiary: "bg-transparent text-gray-1000 hover:bg-gray-alpha-200",
367
+ error: "bg-red-700 text-white [color:white] hover:bg-red-600",
368
+ warning: "bg-amber-700 text-white [color:white] hover:bg-amber-600",
369
+ ghost: "hover:bg-gray-alpha-200 text-gray-1000",
370
+ link: "text-blue-700 underline-offset-4 hover:underline"
371
+ },
372
+ size: {
373
+ small: "h-8 px-3 text-copy-13",
374
+ medium: "h-9 px-4 text-copy-13",
375
+ large: "h-10 px-5 text-copy-14",
376
+ icon: "h-9 w-9"
377
+ }
378
+ },
379
+ defaultVariants: {
380
+ variant: "default",
381
+ size: "medium"
382
+ }
383
+ }
384
+ );
385
+ var Button = React2.forwardRef(
386
+ ({
387
+ className,
388
+ variant,
389
+ size,
390
+ asChild = false,
391
+ loading = false,
392
+ prefix,
393
+ suffix,
394
+ typeName,
395
+ type,
396
+ disabled,
397
+ children,
398
+ ...props
399
+ }, ref) => {
400
+ let resolvedVariant = variant;
401
+ if (!resolvedVariant && type) {
402
+ if (type === "invert") resolvedVariant = "default";
403
+ else if (type === "shadow") resolvedVariant = "secondary";
404
+ else if (type === "unstyled") resolvedVariant = "ghost";
405
+ }
406
+ const Comp = asChild ? import_react_slot.Slot : "button";
407
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
408
+ Comp,
409
+ {
410
+ className: cn(buttonVariants({ variant: resolvedVariant, size, className })),
411
+ ref,
412
+ type: typeName ?? "button",
413
+ disabled: disabled || loading,
414
+ ...props,
415
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spinner, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
416
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "inline-flex shrink-0", children: prefix }),
417
+ children,
418
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "inline-flex shrink-0", children: suffix })
419
+ ] })
420
+ }
421
+ );
422
+ }
423
+ );
424
+ Button.displayName = "Button";
425
+
426
+ // src/components/ContextMenu.tsx
427
+ var ContextMenuPrimitive = __toESM(require("@radix-ui/react-context-menu"), 1);
428
+ var React3 = __toESM(require("react"), 1);
429
+ var import_jsx_runtime6 = require("react/jsx-runtime");
430
+ var ContextMenu = ContextMenuPrimitive.Root;
431
+ var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
432
+ var ContextMenuGroup = ContextMenuPrimitive.Group;
433
+ var ContextMenuPortal = ContextMenuPrimitive.Portal;
434
+ var ContextMenuSub = ContextMenuPrimitive.Sub;
435
+ var ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
436
+ var ContextMenuSubTrigger = React3.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
437
+ ContextMenuPrimitive.SubTrigger,
438
+ {
439
+ ref,
440
+ className: cn(
441
+ "flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-copy-13 outline-none select-none",
442
+ "focus:bg-[var(--khal-menu-hover)]",
443
+ "data-[state=open]:bg-[var(--khal-menu-hover)]",
444
+ inset && "pl-8",
445
+ className
446
+ ),
447
+ style: { color: "var(--khal-text-primary)" },
448
+ ...props,
449
+ children
450
+ }
451
+ ));
452
+ ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
453
+ var ContextMenuSubContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
454
+ ContextMenuPrimitive.SubContent,
455
+ {
456
+ ref,
457
+ className: cn(
458
+ "z-[9999] min-w-[8rem] overflow-hidden rounded-xl p-1",
459
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
460
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
461
+ className
462
+ ),
463
+ style: {
464
+ background: "var(--khal-menu-bg)",
465
+ border: "1px solid var(--khal-menu-border)",
466
+ boxShadow: "var(--khal-menu-shadow)",
467
+ color: "var(--khal-text-primary)"
468
+ },
469
+ ...props
470
+ }
471
+ ));
472
+ ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
473
+ var ContextMenuContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ContextMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
474
+ ContextMenuPrimitive.Content,
475
+ {
476
+ ref,
477
+ className: cn(
478
+ "z-[9999] min-w-[8rem] overflow-hidden rounded-xl p-1",
479
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
480
+ className
481
+ ),
482
+ style: {
483
+ background: "var(--khal-menu-bg)",
484
+ border: "1px solid var(--khal-menu-border)",
485
+ boxShadow: "var(--khal-menu-shadow)",
486
+ color: "var(--khal-text-primary)"
487
+ },
488
+ ...props
489
+ }
490
+ ) }));
491
+ ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
492
+ var ContextMenuItem = React3.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
493
+ ContextMenuPrimitive.Item,
494
+ {
495
+ ref,
496
+ className: cn(
497
+ "relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1.5 text-copy-13 outline-none select-none transition-colors",
498
+ "focus:bg-[var(--khal-menu-hover)]",
499
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
500
+ inset && "pl-8",
501
+ className
502
+ ),
503
+ style: { color: "var(--khal-text-primary)" },
504
+ ...props
505
+ }
506
+ ));
507
+ ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
508
+ var ContextMenuSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
509
+ ContextMenuPrimitive.Separator,
510
+ {
511
+ ref,
512
+ className: cn("-mx-1 my-1 h-px", className),
513
+ style: { background: "var(--khal-border-default)" },
514
+ ...props
515
+ }
516
+ ));
517
+ ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
518
+
519
+ // src/components/command.tsx
520
+ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
521
+ var import_cmdk = require("cmdk");
522
+ var import_lucide_react = require("lucide-react");
523
+ var React4 = __toESM(require("react"), 1);
524
+ var import_jsx_runtime7 = require("react/jsx-runtime");
525
+ var Command = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
526
+ import_cmdk.Command,
527
+ {
528
+ ref,
529
+ className: cn("flex h-full w-full flex-col overflow-hidden rounded-xl bg-background-100 text-gray-1000", className),
530
+ ...props
531
+ }
532
+ ));
533
+ Command.displayName = import_cmdk.Command.displayName;
534
+ function CommandDialog({
535
+ children,
536
+ open,
537
+ onOpenChange,
538
+ ...props
539
+ }) {
540
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DialogPrimitive.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(DialogPrimitive.Portal, { children: [
541
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
542
+ DialogPrimitive.Overlay,
543
+ {
544
+ className: "fixed inset-0 z-[9999] bg-black/40 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
545
+ "cmdk-overlay": ""
546
+ }
547
+ ),
548
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
549
+ DialogPrimitive.Content,
550
+ {
551
+ className: "fixed left-[50%] top-[20%] z-[9999] w-full max-w-lg translate-x-[-50%] overflow-hidden rounded-xl shadow-lg",
552
+ style: {
553
+ background: "var(--khal-menu-bg)",
554
+ border: "1px solid var(--khal-menu-border)",
555
+ boxShadow: "var(--khal-menu-shadow)",
556
+ backdropFilter: "blur(24px)",
557
+ WebkitBackdropFilter: "blur(24px)"
558
+ },
559
+ "cmdk-dialog": "",
560
+ "aria-describedby": void 0,
561
+ children: [
562
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DialogPrimitive.Title, { className: "sr-only", children: "Command palette" }),
563
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
564
+ Command,
565
+ {
566
+ className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-gray-700 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3",
567
+ ...props,
568
+ children
569
+ }
570
+ )
571
+ ]
572
+ }
573
+ )
574
+ ] }) });
575
+ }
576
+ var CommandInput = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
577
+ "div",
578
+ {
579
+ className: "flex items-center px-3",
580
+ style: { borderBottom: "1px solid var(--khal-border-default)" },
581
+ "cmdk-input-wrapper": "",
582
+ children: [
583
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
584
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
585
+ import_cmdk.Command.Input,
586
+ {
587
+ ref,
588
+ className: cn(
589
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-copy-13 outline-none",
590
+ "placeholder:text-gray-700",
591
+ "disabled:cursor-not-allowed disabled:opacity-50",
592
+ className
593
+ ),
594
+ ...props
595
+ }
596
+ )
597
+ ]
598
+ }
599
+ ));
600
+ CommandInput.displayName = import_cmdk.Command.Input.displayName;
601
+ var CommandList = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
602
+ import_cmdk.Command.List,
603
+ {
604
+ ref,
605
+ className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
606
+ ...props
607
+ }
608
+ ));
609
+ CommandList.displayName = import_cmdk.Command.List.displayName;
610
+ var CommandEmpty = React4.forwardRef((props, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_cmdk.Command.Empty, { ref, className: "py-6 text-center text-copy-13 text-gray-700", ...props }));
611
+ CommandEmpty.displayName = import_cmdk.Command.Empty.displayName;
612
+ var CommandGroup = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
613
+ import_cmdk.Command.Group,
614
+ {
615
+ ref,
616
+ className: cn(
617
+ "overflow-hidden p-1 text-gray-1000",
618
+ "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-label-12 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-gray-700",
619
+ className
620
+ ),
621
+ ...props
622
+ }
623
+ ));
624
+ CommandGroup.displayName = import_cmdk.Command.Group.displayName;
625
+ var CommandSeparator = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_cmdk.Command.Separator, { ref, className: cn("-mx-1 h-px bg-gray-alpha-400", className), ...props }));
626
+ CommandSeparator.displayName = import_cmdk.Command.Separator.displayName;
627
+ var CommandItem = React4.forwardRef(({ className, prefix, callback, onSelect, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
628
+ import_cmdk.Command.Item,
629
+ {
630
+ ref,
631
+ onSelect: onSelect ?? callback,
632
+ className: cn(
633
+ "relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1.5 text-copy-13 outline-none select-none",
634
+ "data-[selected=true]:text-gray-1000",
635
+ "data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
636
+ className
637
+ ),
638
+ ...props,
639
+ children: [
640
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-flex shrink-0", children: prefix }),
641
+ children
642
+ ]
643
+ }
644
+ ));
645
+ CommandItem.displayName = import_cmdk.Command.Item.displayName;
646
+ var CommandShortcut = ({ className, ...props }) => {
647
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: cn("ml-auto text-label-12 tracking-widest text-gray-700", className), ...props });
648
+ };
649
+
650
+ // src/components/cost-counter.tsx
651
+ var import_react2 = require("motion/react");
652
+ var import_react3 = require("react");
653
+
654
+ // src/components/number-flow.tsx
655
+ var import_react = __toESM(require("@number-flow/react"), 1);
656
+ var import_jsx_runtime8 = require("react/jsx-runtime");
657
+ function NumberFlow({ transformTiming, spinTiming, opacityTiming, ...props }) {
658
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
659
+ import_react.default,
660
+ {
661
+ transformTiming: transformTiming ?? { duration: 800, easing: "cubic-bezier(0.34, 1.56, 0.64, 1)" },
662
+ spinTiming: spinTiming ?? { duration: 800, easing: "cubic-bezier(0.34, 1.56, 0.64, 1)" },
663
+ opacityTiming: opacityTiming ?? { duration: 350, easing: "ease-out" },
664
+ willChange: true,
665
+ ...props
666
+ }
667
+ );
668
+ }
669
+
670
+ // src/components/cost-counter.tsx
671
+ var import_jsx_runtime9 = require("react/jsx-runtime");
672
+ function CostCounter({ value, suffix, prefix, label, description, budget, budgetColor, className }) {
673
+ const [displayed, setDisplayed] = (0, import_react3.useState)(0);
674
+ const triggered = (0, import_react3.useRef)(false);
675
+ const barRef = (0, import_react3.useRef)(null);
676
+ const barInView = (0, import_react2.useInView)(barRef, { once: true, amount: 0.6 });
677
+ const handleViewport = (0, import_react3.useCallback)(() => {
678
+ if (!triggered.current) {
679
+ triggered.current = true;
680
+ setDisplayed(value);
681
+ }
682
+ }, [value]);
683
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
684
+ import_react2.motion.div,
685
+ {
686
+ onViewportEnter: handleViewport,
687
+ viewport: { once: true, amount: 0.5 },
688
+ className: cn("flex flex-col gap-3", className),
689
+ children: [
690
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
691
+ "div",
692
+ {
693
+ className: "flex items-baseline tabular-nums font-semibold tracking-tight leading-none",
694
+ style: { fontFamily: "var(--font-display, var(--font-geist-sans))" },
695
+ children: [
696
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-[0.7em]", children: prefix }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(NumberFlow, { value: displayed }),
698
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-[0.65em] ml-0.5 opacity-70", children: suffix })
699
+ ]
700
+ }
701
+ ),
702
+ budget != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: barRef, className: "w-full h-2 rounded-full overflow-hidden bg-[var(--ds-gray-alpha-200)]", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
703
+ import_react2.motion.div,
704
+ {
705
+ initial: { width: 0 },
706
+ animate: barInView ? { width: `${Math.min(budget, 100)}%` } : { width: 0 },
707
+ transition: { duration: 1, ease: [0.22, 1, 0.36, 1], delay: 0.15 },
708
+ className: "h-full rounded-full",
709
+ style: { backgroundColor: budgetColor ?? "var(--ds-accent-warm)" }
710
+ }
711
+ ) }),
712
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
713
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm font-medium leading-5", children: label }),
714
+ description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs opacity-50 leading-4", children: description })
715
+ ] })
716
+ ]
717
+ }
718
+ );
719
+ }
720
+
721
+ // src/components/data-row.tsx
722
+ var import_class_variance_authority3 = require("class-variance-authority");
723
+ var React5 = __toESM(require("react"), 1);
724
+ var import_jsx_runtime10 = require("react/jsx-runtime");
725
+ var dataRowVariants = (0, import_class_variance_authority3.cva)("flex items-center gap-3 rounded-lg border border-[#FFFFFF14] font-mono", {
726
+ variants: {
727
+ variant: {
728
+ /** Standard data row — subtle bg */
729
+ default: "bg-[#FFFFFF08] py-2.5 px-3",
730
+ /** Inline/compact — for observability-style data */
731
+ inline: "bg-[#FFFFFF06] py-1.5 px-2.5 text-[11px]",
732
+ /** Nested rule row — for indented rule displays */
733
+ rule: "bg-[#FFFFFF05] py-2.5 px-3"
734
+ }
735
+ },
736
+ defaultVariants: {
737
+ variant: "default"
738
+ }
739
+ });
740
+ var DataRow = React5.forwardRef(
741
+ ({ className, variant, label, value, accentColor, statusDot, dotColor, tag, tagColor, children, ...props }, ref) => {
742
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref, className: cn(dataRowVariants({ variant }), className), ...props, children: [
743
+ statusDot && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "size-[6px] shrink-0 rounded-full", style: { backgroundColor: dotColor || "#FFFFFF40" } }),
744
+ tag && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
745
+ "span",
746
+ {
747
+ className: "shrink-0 rounded py-0.5 px-2 text-[10px] font-bold uppercase tracking-wide leading-3.5",
748
+ style: {
749
+ color: tagColor || "var(--color-accent, #D49355)",
750
+ backgroundColor: tagColor ? `color-mix(in srgb, ${tagColor} 10%, transparent)` : "rgba(var(--color-accent-rgb, 212,147,85), 0.1)"
751
+ },
752
+ children: tag
753
+ }
754
+ ),
755
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[12px] text-[#FFFFFFCC] leading-4 min-w-0 truncate", children: label }),
756
+ (value || children) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "grow" }),
757
+ value && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[12px] leading-4 tabular-nums shrink-0", style: { color: accentColor || "#FFFFFF99" }, children: value }),
758
+ children
759
+ ] });
760
+ }
761
+ );
762
+ DataRow.displayName = "DataRow";
763
+
764
+ // src/components/dropdown-menu.tsx
765
+ var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
766
+ var React6 = __toESM(require("react"), 1);
767
+ var import_jsx_runtime11 = require("react/jsx-runtime");
768
+ var DropdownMenu = DropdownMenuPrimitive.Root;
769
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
770
+ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
771
+ var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
772
+ var DropdownMenuSub = DropdownMenuPrimitive.Sub;
773
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
774
+ var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
775
+ DropdownMenuPrimitive.SubTrigger,
776
+ {
777
+ ref,
778
+ className: cn(
779
+ "flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-copy-13 outline-none select-none",
780
+ "focus:bg-[var(--khal-menu-hover)]",
781
+ "data-[state=open]:bg-[var(--khal-menu-hover)]",
782
+ inset && "pl-8",
783
+ className
784
+ ),
785
+ style: { color: "var(--khal-text-primary)" },
786
+ ...props,
787
+ children
788
+ }
789
+ ));
790
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
791
+ var DropdownMenuSubContent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
792
+ DropdownMenuPrimitive.SubContent,
793
+ {
794
+ ref,
795
+ className: cn(
796
+ "z-[9999] min-w-[8rem] overflow-hidden rounded-xl p-1",
797
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
798
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
799
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
800
+ className
801
+ ),
802
+ style: {
803
+ background: "var(--khal-menu-bg)",
804
+ border: "1px solid var(--khal-menu-border)",
805
+ boxShadow: "var(--khal-menu-shadow)",
806
+ color: "var(--khal-text-primary)"
807
+ },
808
+ ...props
809
+ }
810
+ ));
811
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
812
+ var DropdownMenuContent = React6.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
813
+ DropdownMenuPrimitive.Content,
814
+ {
815
+ ref,
816
+ sideOffset,
817
+ className: cn(
818
+ "z-[9999] min-w-[8rem] overflow-hidden rounded-xl p-1",
819
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
820
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
821
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
822
+ className
823
+ ),
824
+ style: {
825
+ background: "var(--khal-menu-bg)",
826
+ border: "1px solid var(--khal-menu-border)",
827
+ boxShadow: "var(--khal-menu-shadow)",
828
+ color: "var(--khal-text-primary)"
829
+ },
830
+ ...props
831
+ }
832
+ ) }));
833
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
834
+ var DropdownMenuItem = React6.forwardRef(({ className, inset, prefix, suffix, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
835
+ DropdownMenuPrimitive.Item,
836
+ {
837
+ ref,
838
+ className: cn(
839
+ "relative flex cursor-default items-center gap-2 rounded-lg px-2 py-1.5 text-copy-13 outline-none select-none transition-colors",
840
+ "focus:bg-[var(--khal-menu-hover)]",
841
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
842
+ inset && "pl-8",
843
+ className
844
+ ),
845
+ style: { color: "var(--khal-text-primary)" },
846
+ ...props,
847
+ children: [
848
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "inline-flex shrink-0", children: prefix }),
849
+ children,
850
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ml-auto inline-flex shrink-0", style: { color: "var(--khal-text-muted)" }, children: suffix })
851
+ ]
852
+ }
853
+ ));
854
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
855
+ var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
856
+ DropdownMenuPrimitive.CheckboxItem,
857
+ {
858
+ ref,
859
+ className: cn(
860
+ "relative flex cursor-default items-center rounded-lg py-1.5 pl-8 pr-2 text-copy-13 outline-none select-none transition-colors",
861
+ "focus:bg-[var(--khal-menu-hover)]",
862
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
863
+ className
864
+ ),
865
+ style: { color: "var(--khal-text-primary)" },
866
+ checked,
867
+ ...props,
868
+ children: [
869
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
870
+ "path",
871
+ {
872
+ d: "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3354 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.5553 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
873
+ fill: "currentColor",
874
+ fillRule: "evenodd",
875
+ clipRule: "evenodd"
876
+ }
877
+ ) }) }) }),
878
+ children
879
+ ]
880
+ }
881
+ ));
882
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
883
+ var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
884
+ DropdownMenuPrimitive.RadioItem,
885
+ {
886
+ ref,
887
+ className: cn(
888
+ "relative flex cursor-default items-center rounded-lg py-1.5 pl-8 pr-2 text-copy-13 outline-none select-none transition-colors",
889
+ "focus:bg-[var(--khal-menu-hover)]",
890
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
891
+ className
892
+ ),
893
+ style: { color: "var(--khal-text-primary)" },
894
+ ...props,
895
+ children: [
896
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "8", height: "8", viewBox: "0 0 8 8", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "4", cy: "4", r: "4", fill: "currentColor" }) }) }) }),
897
+ children
898
+ ]
899
+ }
900
+ ));
901
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
902
+ var DropdownMenuLabel = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
903
+ DropdownMenuPrimitive.Label,
904
+ {
905
+ ref,
906
+ className: cn("px-2 py-1.5 text-label-12 font-semibold", inset && "pl-8", className),
907
+ style: { color: "var(--khal-text-secondary)" },
908
+ ...props
909
+ }
910
+ ));
911
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
912
+ var DropdownMenuSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
913
+ DropdownMenuPrimitive.Separator,
914
+ {
915
+ ref,
916
+ className: cn("-mx-1 my-1 h-px", className),
917
+ style: { background: "var(--khal-border-default)" },
918
+ ...props
919
+ }
920
+ ));
921
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
922
+ var DropdownMenuShortcut = ({ className, ...props }) => {
923
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
924
+ "span",
925
+ {
926
+ className: cn("ml-auto text-label-12 tracking-widest", className),
927
+ style: { color: "var(--khal-text-muted)" },
928
+ ...props
929
+ }
930
+ );
931
+ };
932
+
933
+ // src/components/glass-card.tsx
934
+ var import_class_variance_authority4 = require("class-variance-authority");
935
+ var React7 = __toESM(require("react"), 1);
936
+ var import_jsx_runtime12 = require("react/jsx-runtime");
937
+ var glassCardVariants = (0, import_class_variance_authority4.cva)(
938
+ "relative overflow-hidden border transition-all [background:var(--khal-glass-tint)] [border-color:var(--khal-glass-border)]",
939
+ {
940
+ variants: {
941
+ variant: {
942
+ default: "[box-shadow:var(--khal-shadow-sm)]",
943
+ raised: "[box-shadow:var(--khal-shadow-md)]"
944
+ },
945
+ padding: {
946
+ sm: "p-3",
947
+ md: "p-4",
948
+ lg: "p-6"
949
+ }
950
+ },
951
+ defaultVariants: {
952
+ variant: "default",
953
+ padding: "md"
954
+ }
955
+ }
956
+ );
957
+ var GlassCard = React7.forwardRef(
958
+ ({ className, variant, padding, hover = false, glow, style, children, ...props }, ref) => {
959
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
960
+ "div",
961
+ {
962
+ ref,
963
+ className: cn(
964
+ glassCardVariants({ variant, padding }),
965
+ hover && [
966
+ "cursor-pointer",
967
+ "hover:-translate-y-0.5",
968
+ "hover:[border-color:var(--khal-border-strong)]",
969
+ "hover:[box-shadow:var(--khal-shadow-lg)]"
970
+ ],
971
+ className
972
+ ),
973
+ style: {
974
+ backdropFilter: "var(--khal-glass-filter)",
975
+ WebkitBackdropFilter: "var(--khal-glass-filter)",
976
+ borderRadius: "var(--khal-radius-xl)",
977
+ transitionTimingFunction: "var(--khal-ease-spring)",
978
+ transitionDuration: "var(--khal-duration-normal)",
979
+ ...style
980
+ },
981
+ ...props,
982
+ children: [
983
+ glow && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
984
+ "div",
985
+ {
986
+ className: "pointer-events-none absolute inset-0 rounded-[inherit]",
987
+ style: {
988
+ background: `radial-gradient(ellipse at 50% 0%, color-mix(in srgb, ${glow} 20%, transparent), transparent 70%)`
989
+ }
990
+ }
991
+ ),
992
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative", children })
993
+ ]
994
+ }
995
+ );
996
+ }
997
+ );
998
+ GlassCard.displayName = "GlassCard";
999
+
1000
+ // src/components/input.tsx
1001
+ var React8 = __toESM(require("react"), 1);
1002
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1003
+ var Input = React8.forwardRef(
1004
+ ({ className, label, size, typeName, type, ...props }, ref) => {
1005
+ const input = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1006
+ "input",
1007
+ {
1008
+ type: typeName ?? type,
1009
+ className: cn(
1010
+ "flex w-full rounded-md border border-gray-alpha-400 bg-background-100 px-3 text-copy-13 text-gray-1000 transition-colors",
1011
+ "file:border-0 file:bg-transparent file:text-sm file:font-medium",
1012
+ "placeholder:text-gray-700",
1013
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-700 focus-visible:ring-offset-1",
1014
+ "disabled:cursor-not-allowed disabled:opacity-50",
1015
+ size === "small" ? "h-8" : size === "large" ? "h-11" : "h-9",
1016
+ className
1017
+ ),
1018
+ ref,
1019
+ ...props
1020
+ }
1021
+ );
1022
+ if (label) {
1023
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1024
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "text-label-13 text-gray-900", children: label }),
1025
+ input
1026
+ ] });
1027
+ }
1028
+ return input;
1029
+ }
1030
+ );
1031
+ Input.displayName = "Input";
1032
+
1033
+ // src/components/khal-logo.tsx
1034
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1035
+ function KhalLogo({ size = 20, variant = "light", className }) {
1036
+ const color = variant === "light" ? "#FFFFFF" : "#0A0A0A";
1037
+ const showFull = size >= 20;
1038
+ if (!showFull) {
1039
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1040
+ "svg",
1041
+ {
1042
+ viewBox: "0 0 156 155",
1043
+ fill: "none",
1044
+ xmlns: "http://www.w3.org/2000/svg",
1045
+ width: size,
1046
+ height: size,
1047
+ className,
1048
+ "aria-label": "K",
1049
+ style: { color },
1050
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1051
+ "path",
1052
+ {
1053
+ d: "M0 0H27.4425V65.9519H71.7054L122.829 0H155.362L95.3869 76.1317L164.657 154.92H128.805L72.5913 92.2878H27.4425V154.92H0V0Z",
1054
+ fill: "currentColor"
1055
+ }
1056
+ )
1057
+ }
1058
+ );
1059
+ }
1060
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1061
+ "svg",
1062
+ {
1063
+ viewBox: "0 0 756 155",
1064
+ fill: "none",
1065
+ xmlns: "http://www.w3.org/2000/svg",
1066
+ width: size * (756 / 155),
1067
+ height: size,
1068
+ className,
1069
+ "aria-label": "khal",
1070
+ style: { color },
1071
+ children: [
1072
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("g", { clipPath: "url(#khal-logo-clip)", children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1074
+ "path",
1075
+ {
1076
+ d: "M616.81 0H644.252V128.584H765.533V154.92H638.499C635.4 154.92 632.524 154.33 629.867 153.149C627.211 151.969 624.924 150.42 623.007 148.502C621.088 146.584 619.539 144.371 618.359 141.863C617.326 139.206 616.81 136.403 616.81 133.453V0Z",
1077
+ fill: "currentColor"
1078
+ }
1079
+ ),
1080
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1081
+ "path",
1082
+ {
1083
+ d: "M443.058 21.2467C445.123 14.4594 448.295 9.22105 452.573 5.53287C456.853 1.8447 462.533 0 469.616 0H519.632C527.009 0 532.911 1.91744 537.337 5.75467C541.763 9.44285 545.009 14.6072 547.076 21.2467L589.125 154.92H560.133L546.411 110.657H461.87L468.73 84.3212H538.665L521.181 26.3359H468.951L430 154.92H400.786L443.058 21.2467Z",
1084
+ fill: "currentColor"
1085
+ }
1086
+ ),
1087
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1088
+ "path",
1089
+ {
1090
+ d: "M190.123 0H217.565V62.6322H344.6V0H372.043V154.92H344.6V88.9681H217.565V154.92H190.123V0Z",
1091
+ fill: "currentColor"
1092
+ }
1093
+ ),
1094
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1095
+ "path",
1096
+ {
1097
+ d: "M0 0H27.4425V65.9519H71.7054L122.829 0H155.362L95.3869 76.1317L164.657 154.92H128.805L72.5913 92.2878H27.4425V154.92H0V0Z",
1098
+ fill: "currentColor"
1099
+ }
1100
+ )
1101
+ ] }),
1102
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("clipPath", { id: "khal-logo-clip", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { width: "756", height: "155", fill: "white" }) }) })
1103
+ ]
1104
+ }
1105
+ );
1106
+ }
1107
+
1108
+ // src/components/live-feed.tsx
1109
+ var import_react4 = require("motion/react");
1110
+ var import_react5 = require("react");
1111
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1112
+ var typeColors = {
1113
+ info: "var(--ds-blue-600)",
1114
+ success: "var(--ds-green-600)",
1115
+ warning: "var(--ds-amber-600)",
1116
+ error: "var(--ds-red-600)",
1117
+ agent: "var(--ds-purple-600)",
1118
+ system: "var(--ds-gray-600)"
1119
+ };
1120
+ function LiveFeed({
1121
+ events: externalEvents,
1122
+ maxVisible = 50,
1123
+ showTimestamps = true,
1124
+ height = 300,
1125
+ className
1126
+ }) {
1127
+ const [events, setEvents] = (0, import_react5.useState)(externalEvents ?? []);
1128
+ const scrollRef = (0, import_react5.useRef)(null);
1129
+ const isAtBottom = (0, import_react5.useRef)(true);
1130
+ (0, import_react5.useEffect)(() => {
1131
+ if (externalEvents) {
1132
+ setEvents((prev) => {
1133
+ const combined = [...prev, ...externalEvents.filter((e) => !prev.some((p) => p.id === e.id))];
1134
+ return combined.slice(-maxVisible);
1135
+ });
1136
+ }
1137
+ }, [externalEvents, maxVisible]);
1138
+ (0, import_react5.useEffect)(() => {
1139
+ const el = scrollRef.current;
1140
+ if (el && isAtBottom.current) {
1141
+ el.scrollTop = el.scrollHeight;
1142
+ }
1143
+ }, [events]);
1144
+ const handleScroll = (0, import_react5.useCallback)(() => {
1145
+ const el = scrollRef.current;
1146
+ if (el) {
1147
+ isAtBottom.current = el.scrollHeight - el.scrollTop - el.clientHeight < 24;
1148
+ }
1149
+ }, []);
1150
+ const formatTime = (d) => d.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
1151
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1152
+ "div",
1153
+ {
1154
+ ref: scrollRef,
1155
+ onScroll: handleScroll,
1156
+ className: cn("overflow-y-auto overflow-x-hidden font-mono text-xs leading-5 scrollbar-thin", className),
1157
+ style: { height },
1158
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react4.AnimatePresence, { initial: false, children: events.map((event) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1159
+ import_react4.motion.div,
1160
+ {
1161
+ initial: { opacity: 0, height: 0 },
1162
+ animate: { opacity: 1, height: "auto" },
1163
+ exit: { opacity: 0, height: 0 },
1164
+ transition: { duration: 0.25, ease: [0.22, 1, 0.36, 1] },
1165
+ className: "flex gap-2 px-2 py-0.5 hover:bg-[var(--ds-gray-alpha-100)]",
1166
+ children: [
1167
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1168
+ "span",
1169
+ {
1170
+ className: "inline-block w-1.5 h-1.5 rounded-full mt-1.5 shrink-0",
1171
+ style: { backgroundColor: typeColors[event.type] }
1172
+ }
1173
+ ),
1174
+ showTimestamps && event.timestamp && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "shrink-0 opacity-40 tabular-nums", children: formatTime(event.timestamp) }),
1175
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "opacity-80 break-words min-w-0", children: event.message })
1176
+ ]
1177
+ },
1178
+ event.id
1179
+ )) })
1180
+ }
1181
+ );
1182
+ }
1183
+
1184
+ // src/components/mesh-gradient.tsx
1185
+ var import_react7 = require("react");
1186
+
1187
+ // src/hooks/useReducedMotion.ts
1188
+ var import_react6 = require("react");
1189
+ function useReducedMotion() {
1190
+ const [reduced, setReduced] = (0, import_react6.useState)(false);
1191
+ (0, import_react6.useEffect)(() => {
1192
+ const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
1193
+ setReduced(mq.matches || document.documentElement.dataset.reduceMotion === "true");
1194
+ const handler = (e) => setReduced(e.matches);
1195
+ mq.addEventListener("change", handler);
1196
+ return () => mq.removeEventListener("change", handler);
1197
+ }, []);
1198
+ return reduced;
1199
+ }
1200
+
1201
+ // src/components/mesh-gradient.tsx
1202
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1203
+ var MeshGradientShader = (0, import_react7.lazy)(() => import("@paper-design/shaders-react").then((m) => ({ default: m.MeshGradient })));
1204
+ function StaticFallback({ colors }) {
1205
+ const bg = colors.length >= 2 ? `linear-gradient(135deg, ${colors[0]} 0%, ${colors[Math.floor(colors.length / 2)]} 50%, ${colors[colors.length - 1]} 100%)` : colors[0] ?? "#0A0A0A";
1206
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { width: "100%", height: "100%", background: bg } });
1207
+ }
1208
+ function MeshGradientInner({ colors, speed = 0.02, className, style }) {
1209
+ const ref = (0, import_react7.useRef)(null);
1210
+ const [visible, setVisible] = (0, import_react7.useState)(false);
1211
+ const reducedMotion = useReducedMotion();
1212
+ (0, import_react7.useEffect)(() => {
1213
+ const el = ref.current;
1214
+ if (!el) return;
1215
+ const observer = new IntersectionObserver(([entry]) => setVisible(entry.isIntersecting), {
1216
+ rootMargin: "100px"
1217
+ });
1218
+ observer.observe(el);
1219
+ return () => observer.disconnect();
1220
+ }, []);
1221
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className, style: { position: "absolute", inset: 0, ...style }, children: visible && !reducedMotion ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react7.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StaticFallback, { colors }), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MeshGradientShader, { colors, speed, style: { width: "100%", height: "100%" } }) }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StaticFallback, { colors }) });
1222
+ }
1223
+
1224
+ // src/components/metric-display.tsx
1225
+ var import_class_variance_authority5 = require("class-variance-authority");
1226
+ var React9 = __toESM(require("react"), 1);
1227
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1228
+ var metricDisplayVariants = (0, import_class_variance_authority5.cva)("flex flex-col", {
1229
+ variants: {
1230
+ size: {
1231
+ /** Compact — for inline/tile use (architecture mockup metric tiles) */
1232
+ sm: "gap-1",
1233
+ /** Standard — for dashboard displays */
1234
+ md: "gap-1.5",
1235
+ /** Large — hero stat cards (metrics.tsx) */
1236
+ lg: "gap-2"
1237
+ }
1238
+ },
1239
+ defaultVariants: {
1240
+ size: "md"
1241
+ }
1242
+ });
1243
+ var valueSizeMap = {
1244
+ sm: "text-[22px] font-semibold leading-7 tracking-tight",
1245
+ md: "text-[28px] font-semibold leading-8 tracking-[-0.02em]",
1246
+ lg: "text-[36px] sm:text-[44px] font-semibold leading-none tracking-[-0.04em]"
1247
+ };
1248
+ var labelSizeMap = {
1249
+ sm: "text-[11px] uppercase tracking-[0.06em] text-[#FFFFFF80] font-medium leading-3.5",
1250
+ md: "text-[13px] text-[#FFFFFFCC] font-medium leading-4",
1251
+ lg: "text-[15px] text-[#FFFFFFCC] font-medium leading-5"
1252
+ };
1253
+ var MetricDisplay = React9.forwardRef(
1254
+ ({ className, size = "md", value, label, description, prefix, suffix, accentColor, ...props }, ref) => {
1255
+ const resolvedSize = size ?? "md";
1256
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref, className: cn(metricDisplayVariants({ size }), className), ...props, children: [
1257
+ resolvedSize === "sm" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: labelSizeMap[resolvedSize], children: label }),
1258
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1259
+ "div",
1260
+ {
1261
+ className: cn(valueSizeMap[resolvedSize], "tabular-nums"),
1262
+ style: accentColor ? { color: accentColor } : void 0,
1263
+ children: [
1264
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: prefix }),
1265
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: value }),
1266
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: resolvedSize === "lg" ? "text-[32px] tracking-[-0.02em] ml-0.5" : "ml-0.5", children: suffix })
1267
+ ]
1268
+ }
1269
+ ),
1270
+ resolvedSize !== "sm" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: labelSizeMap[resolvedSize], children: label }),
1271
+ description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[13px] text-[#FFFFFF80] leading-4", children: description })
1272
+ ] });
1273
+ }
1274
+ );
1275
+ MetricDisplay.displayName = "MetricDisplay";
1276
+
1277
+ // src/components/note.tsx
1278
+ var import_class_variance_authority6 = require("class-variance-authority");
1279
+ var import_lucide_react2 = require("lucide-react");
1280
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1281
+ var noteVariants = (0, import_class_variance_authority6.cva)("flex items-start gap-2 rounded-md border p-3 text-copy-13", {
1282
+ variants: {
1283
+ type: {
1284
+ default: "border-gray-alpha-400 bg-gray-alpha-100 text-gray-900",
1285
+ error: "border-red-300 bg-red-100 text-red-900",
1286
+ warning: "border-amber-300 bg-amber-100 text-amber-900",
1287
+ success: "border-green-300 bg-green-100 text-green-900"
1288
+ },
1289
+ size: {
1290
+ default: "p-3",
1291
+ small: "p-2 text-label-12"
1292
+ }
1293
+ },
1294
+ defaultVariants: {
1295
+ type: "default",
1296
+ size: "default"
1297
+ }
1298
+ });
1299
+ var iconMap = {
1300
+ default: import_lucide_react2.Info,
1301
+ error: import_lucide_react2.AlertCircle,
1302
+ warning: import_lucide_react2.AlertTriangle,
1303
+ success: import_lucide_react2.CheckCircle
1304
+ };
1305
+ function Note({ className, type = "default", size, label, action, children, ...props }) {
1306
+ const Icon2 = iconMap[type];
1307
+ const showLabel = label !== false;
1308
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn(noteVariants({ type, size }), className), role: "alert", ...props, children: [
1309
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon2, { className: "h-4 w-4 shrink-0 mt-0.5" }),
1310
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex-1 min-w-0", children }),
1311
+ action && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "shrink-0", children: action })
1312
+ ] });
1313
+ }
1314
+
1315
+ // src/components/pill-badge.tsx
1316
+ var import_class_variance_authority7 = require("class-variance-authority");
1317
+ var React10 = __toESM(require("react"), 1);
1318
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1319
+ var pillBadgeVariants = (0, import_class_variance_authority7.cva)(
1320
+ "inline-flex items-center gap-1.5 rounded-full font-medium uppercase leading-none whitespace-nowrap",
1321
+ {
1322
+ variants: {
1323
+ variant: {
1324
+ /** Subtle border badge — compliance tags, capability tags */
1325
+ default: "border border-[#FFFFFF26] bg-[#FFFFFF08] text-[#FFFFFFCC]",
1326
+ /** Muted badge — less prominent */
1327
+ muted: "border border-[#FFFFFF14] bg-[#FFFFFF05] text-[#FFFFFFCC]",
1328
+ /** Accent-filled badge — ROI labels, active state badges */
1329
+ accent: "text-[var(--color-accent,#D49355)] bg-[rgba(var(--color-accent-rgb,212,147,85),0.12)]"
1330
+ },
1331
+ size: {
1332
+ sm: "py-1 px-2.5 text-[10px] tracking-[0.08em]",
1333
+ md: "py-1.5 px-3.5 text-[11px] tracking-widest",
1334
+ lg: "py-2 px-4 text-[11px] tracking-widest"
1335
+ }
1336
+ },
1337
+ defaultVariants: {
1338
+ variant: "default",
1339
+ size: "md"
1340
+ }
1341
+ }
1342
+ );
1343
+ var PillBadge = React10.forwardRef(
1344
+ ({ className, variant, size, dot, dotColor, children, ...props }, ref) => {
1345
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { ref, className: cn(pillBadgeVariants({ variant, size }), className), ...props, children: [
1346
+ dot && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "size-1.5 shrink-0 rounded-full", style: { backgroundColor: dotColor || "#FFFFFF40" } }),
1347
+ children
1348
+ ] });
1349
+ }
1350
+ );
1351
+ PillBadge.displayName = "PillBadge";
1352
+
1353
+ // src/components/progress-bar.tsx
1354
+ var import_class_variance_authority8 = require("class-variance-authority");
1355
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1356
+ var progressBarVariants = (0, import_class_variance_authority8.cva)(
1357
+ "relative w-full overflow-hidden rounded-full [background:var(--khal-border-default)]",
1358
+ {
1359
+ variants: {
1360
+ size: {
1361
+ sm: "h-1.5",
1362
+ md: "h-2.5"
1363
+ }
1364
+ },
1365
+ defaultVariants: {
1366
+ size: "md"
1367
+ }
1368
+ }
1369
+ );
1370
+ function ProgressBar({
1371
+ value,
1372
+ max = 100,
1373
+ color = "var(--khal-stage-build)",
1374
+ size,
1375
+ showLabel = false,
1376
+ className,
1377
+ ...props
1378
+ }) {
1379
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
1380
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("flex items-center gap-2", className), ...props, children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1382
+ "div",
1383
+ {
1384
+ role: "progressbar",
1385
+ "aria-valuenow": value,
1386
+ "aria-valuemin": 0,
1387
+ "aria-valuemax": max,
1388
+ className: progressBarVariants({ size }),
1389
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1390
+ "div",
1391
+ {
1392
+ className: "h-full rounded-full",
1393
+ style: {
1394
+ width: `${percentage}%`,
1395
+ background: `linear-gradient(90deg, color-mix(in srgb, ${color} 85%, black), ${color})`,
1396
+ transition: "width var(--khal-duration-normal) var(--khal-ease-spring)"
1397
+ }
1398
+ }
1399
+ )
1400
+ }
1401
+ ),
1402
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "shrink-0 text-xs tabular-nums opacity-60", children: [
1403
+ value,
1404
+ "/",
1405
+ max
1406
+ ] })
1407
+ ] });
1408
+ }
1409
+
1410
+ // src/components/section-card.tsx
1411
+ var import_class_variance_authority9 = require("class-variance-authority");
1412
+ var React11 = __toESM(require("react"), 1);
1413
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1414
+ var sectionCardVariants = (0, import_class_variance_authority9.cva)("relative flex flex-col overflow-hidden", {
1415
+ variants: {
1416
+ variant: {
1417
+ default: "rounded-2xl border border-[#FFFFFF1A] bg-[#FFFFFF0A]",
1418
+ inset: "rounded-tl-xl border-t border-l border-[#FFFFFF26] bg-[#111111]",
1419
+ solid: "rounded-2xl border border-[#FFFFFF1A] bg-[#0D0D0D]"
1420
+ },
1421
+ padding: {
1422
+ none: "",
1423
+ sm: "p-4",
1424
+ md: "p-5 sm:p-6",
1425
+ lg: "p-5 sm:p-6 md:p-8"
1426
+ }
1427
+ },
1428
+ defaultVariants: {
1429
+ variant: "default",
1430
+ padding: "md"
1431
+ }
1432
+ });
1433
+ var SectionCard = React11.forwardRef(
1434
+ ({ className, variant, padding, glow, children, ...props }, ref) => {
1435
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { ref, className: cn(sectionCardVariants({ variant, padding }), className), ...props, children: [
1436
+ glow && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1437
+ "div",
1438
+ {
1439
+ className: "pointer-events-none absolute inset-0 z-0",
1440
+ style: {
1441
+ background: `linear-gradient(180deg, ${glow}22 0%, transparent 60%)`
1442
+ }
1443
+ }
1444
+ ),
1445
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "relative z-10 flex flex-col h-full", children })
1446
+ ] });
1447
+ }
1448
+ );
1449
+ SectionCard.displayName = "SectionCard";
1450
+ function SectionCardHeader({ className, children, ...props }) {
1451
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1452
+ "div",
1453
+ {
1454
+ className: cn("flex items-center justify-between py-3 px-4 border-b border-[#FFFFFF1A]", className),
1455
+ ...props,
1456
+ children
1457
+ }
1458
+ );
1459
+ }
1460
+ SectionCardHeader.displayName = "SectionCardHeader";
1461
+
1462
+ // src/components/separator.tsx
1463
+ var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"), 1);
1464
+ var React12 = __toESM(require("react"), 1);
1465
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1466
+ var Separator3 = React12.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1467
+ SeparatorPrimitive.Root,
1468
+ {
1469
+ ref,
1470
+ decorative,
1471
+ orientation,
1472
+ className: cn(
1473
+ "shrink-0 bg-gray-alpha-400",
1474
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
1475
+ className
1476
+ ),
1477
+ ...props
1478
+ }
1479
+ ));
1480
+ Separator3.displayName = SeparatorPrimitive.Root.displayName;
1481
+
1482
+ // src/components/switch.tsx
1483
+ var SwitchPrimitive = __toESM(require("@radix-ui/react-switch"), 1);
1484
+ var React13 = __toESM(require("react"), 1);
1485
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1486
+ var Toggle = React13.forwardRef(
1487
+ ({ className, onChange, onCheckedChange, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1488
+ SwitchPrimitive.Root,
1489
+ {
1490
+ className: cn(
1491
+ "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors",
1492
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-700 focus-visible:ring-offset-2 focus-visible:ring-offset-background-100",
1493
+ "disabled:cursor-not-allowed disabled:opacity-50",
1494
+ "data-[state=checked]:bg-gray-1000 data-[state=unchecked]:bg-gray-alpha-400",
1495
+ className
1496
+ ),
1497
+ onCheckedChange: onCheckedChange ?? onChange,
1498
+ ...props,
1499
+ ref,
1500
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1501
+ SwitchPrimitive.Thumb,
1502
+ {
1503
+ className: cn(
1504
+ "pointer-events-none block h-4 w-4 rounded-full bg-white shadow-lg ring-0 transition-transform",
1505
+ "data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
1506
+ )
1507
+ }
1508
+ )
1509
+ }
1510
+ )
1511
+ );
1512
+ Toggle.displayName = "Toggle";
1513
+
1514
+ // src/components/theme-provider.tsx
1515
+ var import_next_themes = require("next-themes");
1516
+ var import_react8 = require("react");
1517
+
1518
+ // src/stores/theme-store.ts
1519
+ var import_zustand = require("zustand");
1520
+ var import_middleware = require("zustand/middleware");
1521
+ var useThemeStore = (0, import_zustand.create)()(
1522
+ (0, import_middleware.persist)(
1523
+ (set) => ({
1524
+ mode: "dark",
1525
+ setMode: (mode) => set({ mode }),
1526
+ reduceMotion: false,
1527
+ setReduceMotion: (reduceMotion) => set({ reduceMotion }),
1528
+ glassEnabled: false,
1529
+ setGlassEnabled: (glassEnabled) => set({ glassEnabled }),
1530
+ gpuTerminals: false,
1531
+ setGpuTerminals: (gpuTerminals) => set({ gpuTerminals })
1532
+ }),
1533
+ {
1534
+ name: "khal-theme"
1535
+ }
1536
+ )
1537
+ );
1538
+
1539
+ // src/components/theme-provider.tsx
1540
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1541
+ function ReduceMotionSync() {
1542
+ const reduceMotion = useThemeStore((s) => s.reduceMotion);
1543
+ (0, import_react8.useEffect)(() => {
1544
+ document.documentElement.setAttribute("data-reduce-motion", String(reduceMotion));
1545
+ }, [reduceMotion]);
1546
+ return null;
1547
+ }
1548
+ function GlassSync() {
1549
+ const glassEnabled = useThemeStore((s) => s.glassEnabled);
1550
+ (0, import_react8.useEffect)(() => {
1551
+ const el = document.documentElement;
1552
+ if (glassEnabled) {
1553
+ el.setAttribute("data-glass", "");
1554
+ el.style.setProperty("--khal-glass-enabled", "1");
1555
+ } else {
1556
+ el.removeAttribute("data-glass");
1557
+ el.style.setProperty("--khal-glass-enabled", "0");
1558
+ }
1559
+ }, [glassEnabled]);
1560
+ return null;
1561
+ }
1562
+ function GpuTerminalsSync() {
1563
+ const gpuTerminals = useThemeStore((s) => s.gpuTerminals);
1564
+ (0, import_react8.useEffect)(() => {
1565
+ if (gpuTerminals) {
1566
+ localStorage.setItem("khal-gpu-terminals", "true");
1567
+ } else {
1568
+ localStorage.removeItem("khal-gpu-terminals");
1569
+ }
1570
+ }, [gpuTerminals]);
1571
+ return null;
1572
+ }
1573
+ function ThemeProvider({ children, ...props }) {
1574
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_next_themes.ThemeProvider, { ...props, children: [
1575
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ReduceMotionSync, {}),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GlassSync, {}),
1577
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GpuTerminalsSync, {}),
1578
+ children
1579
+ ] });
1580
+ }
1581
+
1582
+ // src/components/theme-switcher.tsx
1583
+ var import_lucide_react3 = require("lucide-react");
1584
+ var import_next_themes2 = require("next-themes");
1585
+ var import_react9 = require("react");
1586
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1587
+ var themes = [
1588
+ { value: "system", label: "System", icon: import_lucide_react3.Monitor },
1589
+ { value: "light", label: "Light", icon: import_lucide_react3.Sun },
1590
+ { value: "dark", label: "Dark", icon: import_lucide_react3.Moon }
1591
+ ];
1592
+ function ThemeSwitcher({ small, className, onThemeSwitch, disabled }) {
1593
+ const { theme, setTheme } = (0, import_next_themes2.useTheme)();
1594
+ const [mounted, setMounted] = (0, import_react9.useState)(false);
1595
+ (0, import_react9.useEffect)(() => setMounted(true), []);
1596
+ const resolvedTheme = mounted ? theme : void 0;
1597
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1598
+ "fieldset",
1599
+ {
1600
+ className: cn("inline-flex items-center gap-1 rounded-lg bg-gray-alpha-100 p-1", className),
1601
+ disabled,
1602
+ children: themes.map(({ value, label, icon: Icon2 }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1603
+ "button",
1604
+ {
1605
+ type: "button",
1606
+ role: "radio",
1607
+ "aria-checked": resolvedTheme === value,
1608
+ onClick: () => {
1609
+ setTheme(value);
1610
+ onThemeSwitch?.(value);
1611
+ },
1612
+ className: cn(
1613
+ "inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-label-12 transition-colors cursor-pointer",
1614
+ resolvedTheme === value ? "bg-background-100 text-gray-1000 shadow-sm" : "text-gray-700 hover:text-gray-1000"
1615
+ ),
1616
+ children: [
1617
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon2, { className: small ? "h-3.5 w-3.5" : "h-4 w-4" }),
1618
+ !small && label
1619
+ ]
1620
+ },
1621
+ value
1622
+ ))
1623
+ }
1624
+ );
1625
+ }
1626
+
1627
+ // src/components/ticker-bar.tsx
1628
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1629
+ function TickerBar({ children, duration = 30, pauseOnHover = true, className }) {
1630
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1631
+ "div",
1632
+ {
1633
+ className: cn("relative w-full overflow-hidden", className),
1634
+ style: {
1635
+ maskImage: "linear-gradient(to right, transparent, black 10%, black 90%, transparent)",
1636
+ WebkitMaskImage: "linear-gradient(to right, transparent, black 10%, black 90%, transparent)"
1637
+ },
1638
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1639
+ "div",
1640
+ {
1641
+ className: cn("flex w-max", pauseOnHover && "hover:[animation-play-state:paused]"),
1642
+ style: {
1643
+ animation: `khal-ticker ${duration}s linear infinite`
1644
+ },
1645
+ children: [
1646
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex shrink-0 items-center", children }),
1647
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex shrink-0 items-center", "aria-hidden": true, children })
1648
+ ]
1649
+ }
1650
+ )
1651
+ }
1652
+ );
1653
+ }
1654
+
1655
+ // src/components/tooltip.tsx
1656
+ var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
1657
+ var React14 = __toESM(require("react"), 1);
1658
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1659
+ var TooltipProvider = TooltipPrimitive.Provider;
1660
+ var TooltipRoot = TooltipPrimitive.Root;
1661
+ var TooltipTrigger = TooltipPrimitive.Trigger;
1662
+ var TooltipContent = React14.forwardRef(({ className, sideOffset = 4, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1663
+ TooltipPrimitive.Content,
1664
+ {
1665
+ ref,
1666
+ sideOffset,
1667
+ className: cn(
1668
+ "z-[9999] overflow-hidden rounded-md px-2.5 py-1 text-label-12",
1669
+ "animate-in fade-in-0 zoom-in-95",
1670
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
1671
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
1672
+ className
1673
+ ),
1674
+ style: {
1675
+ background: "var(--khal-text-primary, var(--ds-gray-1000))",
1676
+ color: "var(--khal-text-inverse, var(--ds-background-100))",
1677
+ ...style
1678
+ },
1679
+ ...props
1680
+ }
1681
+ ) }));
1682
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
1683
+ function Tooltip({ text, children, position = "top", delay, delayTime, desktopOnly, className }) {
1684
+ const delayDuration = delayTime ?? (delay ? 400 : 200);
1685
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipProvider, { delayDuration, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(TooltipRoot, { children: [
1686
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children }),
1687
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipContent, { side: position, className: cn(desktopOnly && "max-md:hidden", className), children: text })
1688
+ ] }) });
1689
+ }
1690
+
1691
+ // src/components/window-minimized-context.tsx
1692
+ var import_react10 = require("react");
1693
+ var WindowMinimizedContext = (0, import_react10.createContext)(false);
1694
+ var WindowMinimizedProvider = WindowMinimizedContext.Provider;
1695
+ function useWindowMinimized() {
1696
+ return (0, import_react10.useContext)(WindowMinimizedContext);
1697
+ }
1698
+ var WindowActiveContext = (0, import_react10.createContext)(true);
1699
+ var WindowActiveProvider = WindowActiveContext.Provider;
1700
+ function useWindowActive() {
1701
+ return (0, import_react10.useContext)(WindowActiveContext);
1702
+ }
1703
+
1704
+ // src/lib/animations.ts
1705
+ var khalEasing = [0.22, 1, 0.36, 1];
1706
+ var springConfig = {
1707
+ stiffness: 300,
1708
+ damping: 22
1709
+ };
1710
+ var fadeUp = {
1711
+ initial: { opacity: 0, y: 12, filter: "blur(4px)" },
1712
+ animate: { opacity: 1, y: 0, filter: "blur(0px)" },
1713
+ transition: { duration: 0.7, ease: khalEasing }
1714
+ };
1715
+ var scaleUp = {
1716
+ initial: { opacity: 0, scale: 0.96, filter: "blur(6px)" },
1717
+ animate: { opacity: 1, scale: 1, filter: "blur(0px)" },
1718
+ transition: { duration: 0.9, ease: khalEasing }
1719
+ };
1720
+ var staggerContainer = {
1721
+ animate: {
1722
+ transition: {
1723
+ staggerChildren: 0.12
1724
+ }
1725
+ }
1726
+ };
1727
+ var staggerChild = {
1728
+ initial: { opacity: 0, y: 8 },
1729
+ animate: { opacity: 1, y: 0 },
1730
+ transition: { duration: 0.4, ease: khalEasing }
1731
+ };
1732
+ var fadeIn = {
1733
+ initial: { opacity: 0 },
1734
+ animate: { opacity: 1 },
1735
+ transition: { duration: 0.5, ease: khalEasing }
1736
+ };
1737
+
1738
+ // src/primitives/collapsible-sidebar.tsx
1739
+ var import_react11 = require("react");
1740
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1741
+ var SidebarContext = (0, import_react11.createContext)({
1742
+ collapsed: false,
1743
+ toggle: () => {
1744
+ },
1745
+ size: 220
1746
+ });
1747
+ function useSidebar() {
1748
+ return (0, import_react11.useContext)(SidebarContext);
1749
+ }
1750
+ function CollapsibleSidebarRoot({
1751
+ children,
1752
+ defaultSize = 220,
1753
+ min = 140,
1754
+ max = 400,
1755
+ defaultCollapsed = false,
1756
+ side = "left",
1757
+ className = ""
1758
+ }) {
1759
+ const [collapsed, setCollapsed] = (0, import_react11.useState)(defaultCollapsed);
1760
+ const [size, setSize] = (0, import_react11.useState)(defaultSize);
1761
+ const dragging = (0, import_react11.useRef)(false);
1762
+ const startX = (0, import_react11.useRef)(0);
1763
+ const startSize = (0, import_react11.useRef)(0);
1764
+ const toggle = (0, import_react11.useCallback)(() => setCollapsed((v) => !v), []);
1765
+ const onPointerDown = (0, import_react11.useCallback)(
1766
+ (e) => {
1767
+ if (collapsed) return;
1768
+ e.preventDefault();
1769
+ dragging.current = true;
1770
+ startX.current = e.clientX;
1771
+ startSize.current = size;
1772
+ e.target.setPointerCapture(e.pointerId);
1773
+ },
1774
+ [collapsed, size]
1775
+ );
1776
+ const onPointerMove = (0, import_react11.useCallback)(
1777
+ (e) => {
1778
+ if (!dragging.current) return;
1779
+ const delta = side === "left" ? e.clientX - startX.current : startX.current - e.clientX;
1780
+ setSize(Math.min(max, Math.max(min, startSize.current + delta)));
1781
+ },
1782
+ [side, min, max]
1783
+ );
1784
+ const onPointerUp = (0, import_react11.useCallback)(() => {
1785
+ dragging.current = false;
1786
+ }, []);
1787
+ const resizeHandle = /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1788
+ "div",
1789
+ {
1790
+ className: `w-px shrink-0 cursor-col-resize bg-gray-alpha-200 transition-colors hover:w-0.5 hover:bg-blue-700/50 active:w-0.5 active:bg-blue-700 ${collapsed ? "pointer-events-none" : ""}`,
1791
+ onPointerDown,
1792
+ onPointerMove,
1793
+ onPointerUp,
1794
+ role: "separator",
1795
+ "aria-orientation": "vertical"
1796
+ }
1797
+ );
1798
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SidebarContext.Provider, { value: { collapsed, toggle, size }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `flex shrink-0 ${className}`, style: { width: collapsed ? 0 : size }, children: [
1799
+ side === "right" && resizeHandle,
1800
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1801
+ "div",
1802
+ {
1803
+ className: `flex h-full flex-col overflow-hidden transition-[width] duration-150 ${collapsed ? "w-0" : "w-full"}`,
1804
+ children
1805
+ }
1806
+ ),
1807
+ side === "left" && resizeHandle
1808
+ ] }) });
1809
+ }
1810
+ function SidebarHeader({ children, className = "" }) {
1811
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: `flex h-9 shrink-0 items-center justify-between border-b border-gray-alpha-200 px-3 ${className}`, children });
1812
+ }
1813
+ function CollapseButton({ className = "" }) {
1814
+ const { collapsed, toggle } = useSidebar();
1815
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1816
+ "button",
1817
+ {
1818
+ onClick: toggle,
1819
+ className: `inline-flex h-5 w-5 items-center justify-center rounded text-gray-800 hover:bg-gray-alpha-200 hover:text-gray-1000 transition-colors ${className}`,
1820
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
1821
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1822
+ "path",
1823
+ {
1824
+ d: collapsed ? "M4.5 2L8.5 6L4.5 10" : "M8.5 2L4.5 6L8.5 10",
1825
+ stroke: "currentColor",
1826
+ strokeWidth: "1.5",
1827
+ strokeLinecap: "round",
1828
+ strokeLinejoin: "round"
1829
+ }
1830
+ ) })
1831
+ }
1832
+ );
1833
+ }
1834
+ function SidebarContent({ children, className = "" }) {
1835
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: `flex-1 overflow-y-auto ${className}`, children });
1836
+ }
1837
+ function SidebarSection({
1838
+ title,
1839
+ children,
1840
+ className = ""
1841
+ }) {
1842
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `${className}`, children: [
1843
+ title && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "px-3 pt-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-label-13 font-medium text-gray-800", children: title }) }),
1844
+ children
1845
+ ] });
1846
+ }
1847
+ function SidebarItem({ children, icon, active, indent = 0, onClick, className = "" }) {
1848
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1849
+ "button",
1850
+ {
1851
+ onClick,
1852
+ className: `flex w-full items-center gap-2 rounded-md px-2 py-1 text-left text-label-13 transition-colors
1853
+ ${active ? "bg-gray-alpha-200 text-gray-1000" : "text-gray-900 hover:bg-gray-alpha-100 hover:text-gray-1000"}
1854
+ ${className}`,
1855
+ style: { paddingLeft: 8 + indent * 12 },
1856
+ children: [
1857
+ icon && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "shrink-0 text-gray-800 [&>svg]:h-3.5 [&>svg]:w-3.5", children: icon }),
1858
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "min-w-0 truncate", children })
1859
+ ]
1860
+ }
1861
+ );
1862
+ }
1863
+ var CollapsibleSidebar = Object.assign(CollapsibleSidebarRoot, {
1864
+ Header: SidebarHeader,
1865
+ CollapseButton,
1866
+ Content: SidebarContent,
1867
+ Section: SidebarSection,
1868
+ Item: SidebarItem
1869
+ });
1870
+
1871
+ // src/primitives/dialog.tsx
1872
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1873
+ function DialogRoot({ open, onClose, children }) {
1874
+ if (!open) return null;
1875
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1876
+ "div",
1877
+ {
1878
+ className: "bg-popover text-popover-foreground rounded-lg border p-6 shadow-lg",
1879
+ onClick: (e) => e.stopPropagation(),
1880
+ children
1881
+ }
1882
+ ) });
1883
+ }
1884
+ function Body({ children }) {
1885
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex items-start gap-4", children });
1886
+ }
1887
+ function Icon({ children, variant: _variant }) {
1888
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "shrink-0", children });
1889
+ }
1890
+ function Title2({ children }) {
1891
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h2", { className: "text-lg font-semibold", children });
1892
+ }
1893
+ function Description({ children }) {
1894
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-muted-foreground text-sm", children });
1895
+ }
1896
+ function Actions({ children }) {
1897
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-4 flex justify-end gap-2", children });
1898
+ }
1899
+ function Cancel({ children, ...props }) {
1900
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "rounded px-3 py-1.5 text-sm hover:bg-muted", ...props, children });
1901
+ }
1902
+ function Confirm({ children, variant: _variant, ...props }) {
1903
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "rounded bg-destructive px-3 py-1.5 text-sm text-destructive-foreground", ...props, children });
1904
+ }
1905
+ var Dialog = Object.assign(DialogRoot, {
1906
+ Body,
1907
+ Icon,
1908
+ Title: Title2,
1909
+ Description,
1910
+ Actions,
1911
+ Cancel,
1912
+ Confirm
1913
+ });
1914
+
1915
+ // src/primitives/empty-state.tsx
1916
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1917
+ function EmptyState({ icon, title, description, action, compact, className = "" }) {
1918
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1919
+ "div",
1920
+ {
1921
+ className: `flex flex-col items-center justify-center text-center ${compact ? "gap-2 py-6" : "gap-3 py-12"} ${className}`,
1922
+ children: [
1923
+ icon && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: `text-gray-700 ${compact ? "[&>svg]:h-5 [&>svg]:w-5" : "[&>svg]:h-8 [&>svg]:w-8"}`, children: icon }),
1924
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "space-y-0.5", children: [
1925
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-label-13 font-medium text-gray-1000", children: title }),
1926
+ description && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: `text-gray-800 ${compact ? "text-label-13" : "text-label-13"}`, children: description })
1927
+ ] }),
1928
+ action && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "mt-2 shrink-0", children: action })
1929
+ ]
1930
+ }
1931
+ );
1932
+ }
1933
+
1934
+ // src/primitives/list-view.tsx
1935
+ var import_react12 = require("react");
1936
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1937
+ function ListView({
1938
+ items,
1939
+ selected,
1940
+ onSelect,
1941
+ onActivate,
1942
+ renderItem,
1943
+ getKey,
1944
+ multiSelect = false,
1945
+ emptyMessage = "No items",
1946
+ className = ""
1947
+ }) {
1948
+ const [focusIndex, setFocusIndex] = (0, import_react12.useState)(0);
1949
+ const listRef = (0, import_react12.useRef)(null);
1950
+ const selectedSet = new Set(selected == null ? [] : Array.isArray(selected) ? selected : [selected]);
1951
+ const clamp = (0, import_react12.useCallback)((i) => Math.max(0, Math.min(items.length - 1, i)), [items.length]);
1952
+ (0, import_react12.useEffect)(() => {
1953
+ setFocusIndex((prev) => clamp(prev));
1954
+ }, [items.length, clamp]);
1955
+ const scrollToIndex = (0, import_react12.useCallback)((i) => {
1956
+ const el = listRef.current?.children[i];
1957
+ el?.scrollIntoView({ block: "nearest" });
1958
+ }, []);
1959
+ const handleKeyDown = (0, import_react12.useCallback)(
1960
+ (e) => {
1961
+ switch (e.key) {
1962
+ case "ArrowDown": {
1963
+ e.preventDefault();
1964
+ const next = clamp(focusIndex + 1);
1965
+ setFocusIndex(next);
1966
+ scrollToIndex(next);
1967
+ if (!multiSelect) onSelect?.(getKey(items[next]));
1968
+ break;
1969
+ }
1970
+ case "ArrowUp": {
1971
+ e.preventDefault();
1972
+ const prev = clamp(focusIndex - 1);
1973
+ setFocusIndex(prev);
1974
+ scrollToIndex(prev);
1975
+ if (!multiSelect) onSelect?.(getKey(items[prev]));
1976
+ break;
1977
+ }
1978
+ case "Home": {
1979
+ e.preventDefault();
1980
+ setFocusIndex(0);
1981
+ scrollToIndex(0);
1982
+ if (!multiSelect && items.length > 0) onSelect?.(getKey(items[0]));
1983
+ break;
1984
+ }
1985
+ case "End": {
1986
+ e.preventDefault();
1987
+ const last = items.length - 1;
1988
+ setFocusIndex(last);
1989
+ scrollToIndex(last);
1990
+ if (!multiSelect && items.length > 0) onSelect?.(getKey(items[last]));
1991
+ break;
1992
+ }
1993
+ case "Enter":
1994
+ case " ": {
1995
+ e.preventDefault();
1996
+ const item = items[focusIndex];
1997
+ if (item) {
1998
+ onSelect?.(getKey(item));
1999
+ if (e.key === "Enter") onActivate?.(item);
2000
+ }
2001
+ break;
2002
+ }
2003
+ }
2004
+ },
2005
+ [focusIndex, items, clamp, scrollToIndex, onSelect, onActivate, getKey, multiSelect]
2006
+ );
2007
+ if (items.length === 0) {
2008
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: `flex h-full items-center justify-center text-label-13 text-gray-800 ${className}`, children: emptyMessage });
2009
+ }
2010
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2011
+ "div",
2012
+ {
2013
+ ref: listRef,
2014
+ className: `overflow-y-auto outline-none ${className}`,
2015
+ role: "listbox",
2016
+ tabIndex: 0,
2017
+ onKeyDown: handleKeyDown,
2018
+ "aria-multiselectable": multiSelect,
2019
+ children: items.map((item, i) => {
2020
+ const key = getKey(item);
2021
+ const isSelected = selectedSet.has(key);
2022
+ const isFocused = i === focusIndex;
2023
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2024
+ "div",
2025
+ {
2026
+ role: "option",
2027
+ "aria-selected": isSelected,
2028
+ className: `cursor-default select-none px-2 py-1 transition-colors
2029
+ ${isSelected ? "bg-blue-700/15 text-gray-1000" : "text-gray-1000"}
2030
+ ${isFocused && !isSelected ? "bg-gray-alpha-100" : ""}
2031
+ hover:bg-gray-alpha-200`,
2032
+ onClick: () => {
2033
+ setFocusIndex(i);
2034
+ onSelect?.(key);
2035
+ },
2036
+ onDoubleClick: () => onActivate?.(item),
2037
+ children: renderItem(item, { selected: isSelected, focused: isFocused, index: i })
2038
+ },
2039
+ key
2040
+ );
2041
+ })
2042
+ }
2043
+ );
2044
+ }
2045
+
2046
+ // src/primitives/property-panel.tsx
2047
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2048
+ function PropertyPanelRoot({ title, children, className = "" }) {
2049
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `flex flex-col overflow-y-auto ${className}`, children: [
2050
+ title && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "sticky top-0 z-10 border-b border-gray-alpha-200 bg-background-100 px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h3", { className: "text-label-13 font-medium text-gray-1000", children: title }) }),
2051
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-col", children })
2052
+ ] });
2053
+ }
2054
+ function PropertySection({
2055
+ title,
2056
+ children,
2057
+ collapsible: _collapsible = false,
2058
+ defaultOpen: _defaultOpen = true
2059
+ }) {
2060
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "border-b border-gray-alpha-200 last:border-b-0", children: [
2061
+ title && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "px-3 pt-3 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-label-13 font-medium text-gray-800", children: title }) }),
2062
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: `px-3 pb-2 ${title ? "" : "pt-2"}`, children })
2063
+ ] });
2064
+ }
2065
+ function PropertyRow({ label, value, children, mono }) {
2066
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-baseline justify-between gap-4 py-1", children: [
2067
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("dt", { className: "shrink-0 text-label-13 text-gray-800", children: label }),
2068
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("dd", { className: `min-w-0 truncate text-right text-label-13 text-gray-1000 ${mono ? "font-mono" : ""}`, children: children ?? value })
2069
+ ] });
2070
+ }
2071
+ function PropertySeparator() {
2072
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Separator3, { className: "my-1" });
2073
+ }
2074
+ var PropertyPanel = Object.assign(PropertyPanelRoot, {
2075
+ Section: PropertySection,
2076
+ Row: PropertyRow,
2077
+ Separator: PropertySeparator
2078
+ });
2079
+
2080
+ // src/primitives/section-header.tsx
2081
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2082
+ function SectionHeader({
2083
+ title,
2084
+ description,
2085
+ children
2086
+ }) {
2087
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "mb-4 flex items-start justify-between", children: [
2088
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
2089
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h2", { className: "text-copy-13 font-medium text-gray-1000", children: title }),
2090
+ description && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "mt-0.5 text-copy-13 text-gray-900", children: description })
2091
+ ] }),
2092
+ children
2093
+ ] });
2094
+ }
2095
+
2096
+ // src/primitives/sidebar-nav.tsx
2097
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2098
+ function SidebarNavRoot({ children, label, title, className = "" }) {
2099
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("nav", { className: `flex flex-col py-2 ${className}`, "aria-label": label, children: [
2100
+ title && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-copy-13 font-medium text-gray-800", children: title }) }),
2101
+ children
2102
+ ] });
2103
+ }
2104
+ function SidebarNavGroup({ children, title, className = "" }) {
2105
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className, children: [
2106
+ title && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 pt-4 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-copy-13 font-medium text-gray-800", children: title }) }),
2107
+ children
2108
+ ] });
2109
+ }
2110
+ function SidebarNavItem({ children, active, onClick, icon, suffix, className = "" }) {
2111
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2112
+ "button",
2113
+ {
2114
+ onClick,
2115
+ className: `mx-1 flex items-center gap-2 rounded-md px-2 py-1 text-copy-13 transition-colors ${active ? "bg-gray-alpha-200 text-gray-1000" : "text-gray-900 hover:bg-gray-alpha-100 hover:text-gray-1000"} ${className}`,
2116
+ children: [
2117
+ icon && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "shrink-0 text-gray-800 [&>svg]:h-3.5 [&>svg]:w-3.5", children: icon }),
2118
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "min-w-0 truncate", children }),
2119
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ml-auto font-mono text-copy-13 tabular-nums text-gray-700", children: suffix })
2120
+ ]
2121
+ }
2122
+ );
2123
+ }
2124
+ var SidebarNav = Object.assign(SidebarNavRoot, {
2125
+ Group: SidebarNavGroup,
2126
+ Item: SidebarNavItem
2127
+ });
2128
+
2129
+ // src/primitives/split-pane.tsx
2130
+ var import_react13 = require("react");
2131
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2132
+ function useMediaQuery(query) {
2133
+ const subscribe = (0, import_react13.useCallback)(
2134
+ (callback) => {
2135
+ const mql = window.matchMedia(query);
2136
+ mql.addEventListener("change", callback);
2137
+ return () => mql.removeEventListener("change", callback);
2138
+ },
2139
+ [query]
2140
+ );
2141
+ const getSnapshot = (0, import_react13.useCallback)(() => window.matchMedia(query).matches, [query]);
2142
+ const getServerSnapshot = (0, import_react13.useCallback)(() => false, []);
2143
+ return (0, import_react13.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
2144
+ }
2145
+ function SplitPaneRoot({
2146
+ children,
2147
+ direction = "horizontal",
2148
+ defaultSize = 240,
2149
+ min = 100,
2150
+ max = 600,
2151
+ collapseBelow = 640,
2152
+ onResize,
2153
+ className = ""
2154
+ }) {
2155
+ const [size, setSize] = (0, import_react13.useState)(defaultSize);
2156
+ const containerRef = (0, import_react13.useRef)(null);
2157
+ const dragging = (0, import_react13.useRef)(false);
2158
+ const startPos = (0, import_react13.useRef)(0);
2159
+ const startSize = (0, import_react13.useRef)(0);
2160
+ const isMobile = useMediaQuery(`(max-width: ${collapseBelow}px)`);
2161
+ const isHorizontal = direction === "horizontal" && !isMobile;
2162
+ const [first, second] = children;
2163
+ const onPointerDown = (0, import_react13.useCallback)(
2164
+ (e) => {
2165
+ e.preventDefault();
2166
+ dragging.current = true;
2167
+ startPos.current = isHorizontal ? e.clientX : e.clientY;
2168
+ startSize.current = size;
2169
+ e.target.setPointerCapture(e.pointerId);
2170
+ },
2171
+ [isHorizontal, size]
2172
+ );
2173
+ const onPointerMove = (0, import_react13.useCallback)(
2174
+ (e) => {
2175
+ if (!dragging.current) return;
2176
+ const delta = (isHorizontal ? e.clientX : e.clientY) - startPos.current;
2177
+ const next = Math.min(max, Math.max(min, startSize.current + delta));
2178
+ setSize(next);
2179
+ onResize?.(next);
2180
+ },
2181
+ [isHorizontal, min, max, onResize]
2182
+ );
2183
+ const onPointerUp = (0, import_react13.useCallback)(() => {
2184
+ dragging.current = false;
2185
+ }, []);
2186
+ if (isMobile) {
2187
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { ref: containerRef, className: `flex flex-col h-full w-full overflow-hidden ${className}`, children: [
2188
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "shrink-0 overflow-auto border-b border-gray-alpha-200", children: first }),
2189
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex-1 overflow-hidden", children: second })
2190
+ ] });
2191
+ }
2192
+ const firstStyle = isHorizontal ? { width: size, minWidth: min, maxWidth: max, flexShrink: 0 } : { height: size, minHeight: min, maxHeight: max, flexShrink: 0 };
2193
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
2194
+ "div",
2195
+ {
2196
+ ref: containerRef,
2197
+ className: `flex ${isHorizontal ? "flex-row" : "flex-col"} h-full w-full overflow-hidden ${className}`,
2198
+ children: [
2199
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { style: firstStyle, className: "overflow-hidden", children: first }),
2200
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2201
+ "div",
2202
+ {
2203
+ className: `shrink-0 ${isHorizontal ? "w-px cursor-col-resize hover:w-0.5 hover:bg-blue-700/50 active:w-0.5 active:bg-blue-700" : "h-px cursor-row-resize hover:h-0.5 hover:bg-blue-700/50 active:h-0.5 active:bg-blue-700"} bg-gray-alpha-200 transition-colors`,
2204
+ onPointerDown,
2205
+ onPointerMove,
2206
+ onPointerUp,
2207
+ role: "separator",
2208
+ "aria-orientation": isHorizontal ? "vertical" : "horizontal",
2209
+ tabIndex: 0
2210
+ }
2211
+ ),
2212
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex-1 overflow-hidden", children: second })
2213
+ ]
2214
+ }
2215
+ );
2216
+ }
2217
+ function Panel({ children, className = "" }) {
2218
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: `h-full w-full overflow-auto ${className}`, children });
2219
+ }
2220
+ var SplitPane = Object.assign(SplitPaneRoot, {
2221
+ Panel
2222
+ });
2223
+
2224
+ // src/primitives/status-badge.tsx
2225
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2226
+ function StatusBadge({ status }) {
2227
+ const variant = status === "active" ? "green" : status === "creating" ? "amber" : status === "error" ? "red" : "gray";
2228
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Badge, { variant, size: "sm", contrast: "low", children: status });
2229
+ }
2230
+
2231
+ // src/primitives/status-bar.tsx
2232
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2233
+ function StatusBarRoot({ children, className = "" }) {
2234
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2235
+ "div",
2236
+ {
2237
+ className: `flex h-6 shrink-0 items-center gap-0 border-t border-gray-alpha-200 bg-background-100 px-2 font-mono text-label-13 text-gray-900 ${className}`,
2238
+ role: "status",
2239
+ children
2240
+ }
2241
+ );
2242
+ }
2243
+ var variantColors = {
2244
+ default: "text-gray-900",
2245
+ success: "text-green-900",
2246
+ warning: "text-amber-900",
2247
+ error: "text-red-900"
2248
+ };
2249
+ function StatusBarItem({ children, icon, variant = "default", onClick, className = "" }) {
2250
+ const classes = `inline-flex items-center gap-1 px-1.5 py-0.5 rounded-sm ${variantColors[variant]} ${onClick ? "cursor-pointer hover:bg-gray-alpha-200 transition-colors" : ""} ${className}`;
2251
+ if (onClick) {
2252
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("button", { className: classes, onClick, children: [
2253
+ icon,
2254
+ children
2255
+ ] });
2256
+ }
2257
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: classes, children: [
2258
+ icon,
2259
+ children
2260
+ ] });
2261
+ }
2262
+ function StatusBarSeparator() {
2263
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Separator3, { orientation: "vertical", className: "mx-0.5 h-3" });
2264
+ }
2265
+ function StatusBarSpacer() {
2266
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex-1" });
2267
+ }
2268
+ var StatusBar = Object.assign(StatusBarRoot, {
2269
+ Item: StatusBarItem,
2270
+ Separator: StatusBarSeparator,
2271
+ Spacer: StatusBarSpacer
2272
+ });
2273
+
2274
+ // src/primitives/toolbar.tsx
2275
+ var import_react14 = require("react");
2276
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2277
+ function ToolbarRoot({ children, className = "" }) {
2278
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2279
+ "div",
2280
+ {
2281
+ className: `flex h-9 shrink-0 items-center gap-0.5 border-b border-gray-alpha-200 bg-background-100 px-1.5 ${className}`,
2282
+ role: "toolbar",
2283
+ children
2284
+ }
2285
+ );
2286
+ }
2287
+ var ToolbarButton = (0, import_react14.forwardRef)(function ToolbarButton2({ tooltip, active, children, className = "", disabled, ...props }, ref) {
2288
+ const btn = /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2289
+ "button",
2290
+ {
2291
+ ref,
2292
+ disabled,
2293
+ className: `inline-flex h-7 w-7 items-center justify-center rounded-md text-gray-900 transition-colors [&>svg]:h-3.5 [&>svg]:w-3.5
2294
+ hover:bg-gray-alpha-200 hover:text-gray-1000
2295
+ disabled:pointer-events-none disabled:opacity-40
2296
+ ${active ? "bg-gray-alpha-200 text-gray-1000" : ""}
2297
+ ${className}`,
2298
+ ...props,
2299
+ children
2300
+ }
2301
+ );
2302
+ if (tooltip) {
2303
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Tooltip, { text: tooltip, desktopOnly: true, children: btn });
2304
+ }
2305
+ return btn;
2306
+ });
2307
+ function ToolbarGroup({ children, className = "" }) {
2308
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: `flex items-center gap-px ${className}`, children });
2309
+ }
2310
+ function ToolbarSeparator() {
2311
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Separator3, { orientation: "vertical", className: "mx-1 h-4" });
2312
+ }
2313
+ function ToolbarSpacer() {
2314
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex-1" });
2315
+ }
2316
+ function ToolbarText({ children, className = "" }) {
2317
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: `px-1.5 text-label-13 text-gray-900 ${className}`, children });
2318
+ }
2319
+ function ToolbarInput({
2320
+ value,
2321
+ onChange,
2322
+ placeholder,
2323
+ className = "",
2324
+ readOnly
2325
+ }) {
2326
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2327
+ "input",
2328
+ {
2329
+ type: "text",
2330
+ value,
2331
+ onChange,
2332
+ placeholder,
2333
+ readOnly,
2334
+ className: `h-6 flex-1 rounded-md border border-gray-alpha-200 bg-gray-alpha-100 px-2 font-mono text-label-13 text-gray-1000 placeholder:text-gray-700 outline-none transition-colors focus:border-blue-700 ${className}`
2335
+ }
2336
+ );
2337
+ }
2338
+ var Toolbar = Object.assign(ToolbarRoot, {
2339
+ Button: ToolbarButton,
2340
+ Group: ToolbarGroup,
2341
+ Separator: ToolbarSeparator,
2342
+ Spacer: ToolbarSpacer,
2343
+ Text: ToolbarText,
2344
+ Input: ToolbarInput
2345
+ });
2346
+
2347
+ // src/stores/notification-store.ts
2348
+ var import_zustand2 = require("zustand");
2349
+ var MAX_VISIBLE = 5;
2350
+ var MAX_HISTORY = 50;
2351
+ var PREFS_KEY = "khal_os_notification_prefs";
2352
+ function loadPrefs() {
2353
+ if (typeof window === "undefined") return { doNotDisturb: false, desktopNotifMode: "background" };
2354
+ try {
2355
+ const raw = localStorage.getItem(PREFS_KEY);
2356
+ if (raw) return JSON.parse(raw);
2357
+ } catch {
2358
+ }
2359
+ return { doNotDisturb: false, desktopNotifMode: "background" };
2360
+ }
2361
+ function savePrefs(prefs) {
2362
+ try {
2363
+ localStorage.setItem(PREFS_KEY, JSON.stringify(prefs));
2364
+ } catch {
2365
+ }
2366
+ }
2367
+ function getBrowserPermission() {
2368
+ if (typeof window === "undefined" || !("Notification" in window)) return "denied";
2369
+ return Notification.permission;
2370
+ }
2371
+ function sendBrowserNotification(notif) {
2372
+ if (typeof window === "undefined" || !("Notification" in window) || Notification.permission !== "granted") return;
2373
+ const n = new Notification(notif.summary, {
2374
+ body: notif.body || void 0,
2375
+ icon: notif.icon || void 0,
2376
+ tag: String(notif.id),
2377
+ silent: notif.urgency === "low"
2378
+ });
2379
+ n.onclick = () => {
2380
+ window.focus();
2381
+ n.close();
2382
+ };
2383
+ if (notif.expires > 0) {
2384
+ setTimeout(() => n.close(), notif.expires);
2385
+ } else if (notif.urgency !== "critical") {
2386
+ setTimeout(() => n.close(), 6e3);
2387
+ }
2388
+ }
2389
+ var initialPrefs = loadPrefs();
2390
+ var useNotificationStore = (0, import_zustand2.create)()((set, get) => ({
2391
+ notifications: [],
2392
+ history: [],
2393
+ trayIcons: /* @__PURE__ */ new Map(),
2394
+ centerOpen: false,
2395
+ unreadCount: 0,
2396
+ doNotDisturb: initialPrefs.doNotDisturb,
2397
+ desktopNotifMode: initialPrefs.desktopNotifMode,
2398
+ browserPermission: getBrowserPermission(),
2399
+ setDoNotDisturb: (value) => {
2400
+ set({ doNotDisturb: value });
2401
+ savePrefs({ doNotDisturb: value, desktopNotifMode: get().desktopNotifMode });
2402
+ },
2403
+ setDesktopNotifMode: (mode) => {
2404
+ set({ desktopNotifMode: mode });
2405
+ savePrefs({ doNotDisturb: get().doNotDisturb, desktopNotifMode: mode });
2406
+ },
2407
+ requestBrowserPermission: async () => {
2408
+ if (typeof window === "undefined" || !("Notification" in window)) return "denied";
2409
+ const result = await Notification.requestPermission();
2410
+ set({ browserPermission: result });
2411
+ return result;
2412
+ },
2413
+ syncBrowserPermission: () => {
2414
+ set({ browserPermission: getBrowserPermission() });
2415
+ },
2416
+ addNotification: (notification) => {
2417
+ const full = {
2418
+ ...notification,
2419
+ appName: notification.appName ?? "",
2420
+ urgency: notification.urgency ?? "normal",
2421
+ category: notification.category ?? null,
2422
+ transient: notification.transient ?? false,
2423
+ workspaceId: notification.workspaceId ?? null,
2424
+ timestamp: Date.now(),
2425
+ read: false
2426
+ };
2427
+ const { doNotDisturb, desktopNotifMode, browserPermission } = get();
2428
+ set((state) => {
2429
+ const history = full.transient ? state.history : [full, ...state.history].slice(0, MAX_HISTORY);
2430
+ if (doNotDisturb && full.urgency !== "critical") {
2431
+ return {
2432
+ history,
2433
+ unreadCount: full.transient ? state.unreadCount : state.unreadCount + 1
2434
+ };
2435
+ }
2436
+ let notifications = [...state.notifications];
2437
+ if (notification.replacesId) {
2438
+ notifications = notifications.filter((n) => n.id !== notification.replacesId);
2439
+ }
2440
+ notifications = [full, ...notifications].slice(0, MAX_VISIBLE);
2441
+ return {
2442
+ notifications,
2443
+ history,
2444
+ unreadCount: full.transient ? state.unreadCount : state.unreadCount + 1
2445
+ };
2446
+ });
2447
+ if (browserPermission === "granted" && desktopNotifMode !== "off" && !full.transient) {
2448
+ const shouldSend = desktopNotifMode === "always" || desktopNotifMode === "background" && document.hidden;
2449
+ if (shouldSend) {
2450
+ sendBrowserNotification(full);
2451
+ }
2452
+ }
2453
+ const isCritical = full.urgency === "critical";
2454
+ if (full.expires > 0) {
2455
+ setTimeout(() => {
2456
+ get().hideNotification(full.id);
2457
+ }, full.expires);
2458
+ } else if (!isCritical) {
2459
+ setTimeout(() => {
2460
+ get().hideNotification(full.id);
2461
+ }, 6e3);
2462
+ }
2463
+ },
2464
+ dismissNotification: (id) => {
2465
+ set((state) => ({
2466
+ notifications: state.notifications.filter((n) => n.id !== id)
2467
+ }));
2468
+ },
2469
+ hideNotification: (id) => {
2470
+ set((state) => ({
2471
+ notifications: state.notifications.filter((n) => n.id !== id)
2472
+ }));
2473
+ },
2474
+ clearHistory: () => {
2475
+ set({ history: [], unreadCount: 0 });
2476
+ },
2477
+ markAllRead: () => {
2478
+ set((state) => ({
2479
+ history: state.history.map((n) => ({ ...n, read: true })),
2480
+ unreadCount: 0
2481
+ }));
2482
+ },
2483
+ toggleCenter: () => {
2484
+ const opening = !get().centerOpen;
2485
+ set({ centerOpen: opening });
2486
+ if (opening) {
2487
+ get().markAllRead();
2488
+ }
2489
+ },
2490
+ closeCenter: () => {
2491
+ set({ centerOpen: false });
2492
+ },
2493
+ addTrayIcon: (icon) => {
2494
+ set((state) => {
2495
+ const next = new Map(state.trayIcons);
2496
+ next.set(icon.wid, icon);
2497
+ return { trayIcons: next };
2498
+ });
2499
+ },
2500
+ removeTrayIcon: (wid) => {
2501
+ set((state) => {
2502
+ const next = new Map(state.trayIcons);
2503
+ next.delete(wid);
2504
+ return { trayIcons: next };
2505
+ });
2506
+ },
2507
+ updateTrayIcon: (wid, updates) => {
2508
+ set((state) => {
2509
+ const next = new Map(state.trayIcons);
2510
+ const existing = next.get(wid);
2511
+ if (existing) {
2512
+ next.set(wid, { ...existing, ...updates });
2513
+ }
2514
+ return { trayIcons: next };
2515
+ });
2516
+ }
2517
+ }));
2518
+
2519
+ // src/tokens/lp-tokens.ts
2520
+ var WIN_BG = "#111318";
2521
+ var CHROME_BG = "#0D0F14";
2522
+ var CELL_BG = "#0D1017";
2523
+ var WIN_BORDER = "#1E2330";
2524
+ var WIN_BORDER_FOCUSED = "#333D55";
2525
+ var TEXT_PRIMARY = "#E8EAF0";
2526
+ var TEXT_SECONDARY = "#8B92A5";
2527
+ var TEXT_TERTIARY = "#555D73";
2528
+ var ACCENT_BLUE = "#0A6FE0";
2529
+ var MESH_GRADIENT_PALETTE = [
2530
+ "#030508",
2531
+ "#070D15",
2532
+ "#0C1A2E",
2533
+ "#1A4A7A",
2534
+ "#2A3040",
2535
+ "#5C4A38",
2536
+ "#8B6B42",
2537
+ "#D49355"
2538
+ ];
2539
+ var WINDOW_RADIUS = "12px";
2540
+ var BUTTON_RADIUS = "10px";
2541
+ // Annotate the CommonJS export names for ESM import in node:
2542
+ 0 && (module.exports = {
2543
+ ACCENT_BLUE,
2544
+ Avatar,
2545
+ BUTTON_RADIUS,
2546
+ Badge,
2547
+ Button,
2548
+ CELL_BG,
2549
+ CHROME_BG,
2550
+ CollapsibleSidebar,
2551
+ Command,
2552
+ CommandDialog,
2553
+ CommandEmpty,
2554
+ CommandGroup,
2555
+ CommandInput,
2556
+ CommandItem,
2557
+ CommandList,
2558
+ CommandSeparator,
2559
+ CommandShortcut,
2560
+ ContextMenu,
2561
+ ContextMenuContent,
2562
+ ContextMenuGroup,
2563
+ ContextMenuItem,
2564
+ ContextMenuPortal,
2565
+ ContextMenuRadioGroup,
2566
+ ContextMenuSeparator,
2567
+ ContextMenuSub,
2568
+ ContextMenuSubContent,
2569
+ ContextMenuSubTrigger,
2570
+ ContextMenuTrigger,
2571
+ CostCounter,
2572
+ DataRow,
2573
+ Dialog,
2574
+ DropdownMenu,
2575
+ DropdownMenuCheckboxItem,
2576
+ DropdownMenuContent,
2577
+ DropdownMenuGroup,
2578
+ DropdownMenuItem,
2579
+ DropdownMenuLabel,
2580
+ DropdownMenuPortal,
2581
+ DropdownMenuRadioGroup,
2582
+ DropdownMenuRadioItem,
2583
+ DropdownMenuSeparator,
2584
+ DropdownMenuShortcut,
2585
+ DropdownMenuSub,
2586
+ DropdownMenuSubContent,
2587
+ DropdownMenuSubTrigger,
2588
+ DropdownMenuTrigger,
2589
+ EmptyState,
2590
+ GlassCard,
2591
+ Input,
2592
+ KhalLogo,
2593
+ ListView,
2594
+ LiveFeed,
2595
+ MESH_GRADIENT_PALETTE,
2596
+ MeshGradient,
2597
+ MetricDisplay,
2598
+ Note,
2599
+ NumberFlow,
2600
+ PillBadge,
2601
+ ProgressBar,
2602
+ PropertyPanel,
2603
+ SUBJECTS,
2604
+ SectionCard,
2605
+ SectionCardHeader,
2606
+ SectionHeader,
2607
+ Separator,
2608
+ SidebarNav,
2609
+ Spinner,
2610
+ SplitPane,
2611
+ StatusBadge,
2612
+ StatusBar,
2613
+ StatusDot,
2614
+ TEXT_PRIMARY,
2615
+ TEXT_SECONDARY,
2616
+ TEXT_TERTIARY,
2617
+ ThemeProvider,
2618
+ ThemeSwitcher,
2619
+ TickerBar,
2620
+ Toggle,
2621
+ Toolbar,
2622
+ Tooltip,
2623
+ TooltipContent,
2624
+ TooltipProvider,
2625
+ TooltipRoot,
2626
+ TooltipTrigger,
2627
+ WINDOW_RADIUS,
2628
+ WIN_BG,
2629
+ WIN_BORDER,
2630
+ WIN_BORDER_FOCUSED,
2631
+ WindowActiveProvider,
2632
+ WindowMinimizedProvider,
2633
+ badgeVariants,
2634
+ buttonVariants,
2635
+ cn,
2636
+ dataRowVariants,
2637
+ fadeIn,
2638
+ fadeUp,
2639
+ glassCardVariants,
2640
+ khalEasing,
2641
+ metricDisplayVariants,
2642
+ pillBadgeVariants,
2643
+ progressBarVariants,
2644
+ scaleUp,
2645
+ sectionCardVariants,
2646
+ springConfig,
2647
+ staggerChild,
2648
+ staggerContainer,
2649
+ stateConfig,
2650
+ useKhalAuth,
2651
+ useNats,
2652
+ useNatsSubscription,
2653
+ useNotificationStore,
2654
+ useOSAuth,
2655
+ useReducedMotion,
2656
+ useSidebar,
2657
+ useThemeStore,
2658
+ useWindowActive,
2659
+ useWindowMinimized
2660
+ });
2661
+ //# sourceMappingURL=index.cjs.map