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