@lessly/ui 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2444,15 +2444,185 @@ var EmptyState = React42.forwardRef(
2444
2444
  );
2445
2445
  EmptyState.displayName = "EmptyState";
2446
2446
 
2447
- // src/components/copy-button.tsx
2447
+ // src/components/sign-in-screen.tsx
2448
2448
  import * as React43 from "react";
2449
+ import { Fragment, jsx as jsx49, jsxs as jsxs23 } from "react/jsx-runtime";
2450
+ var GLOW_BG = "radial-gradient(560px 320px at 28% 16%, var(--auth-glow-a), transparent 68%),radial-gradient(520px 340px at 78% 90%, var(--auth-glow-b), transparent 66%),var(--bg-sunken)";
2451
+ var DEFAULT_TITLE = {
2452
+ login: "Sign in",
2453
+ forbidden: "Access restricted",
2454
+ error: "Couldn't load"
2455
+ };
2456
+ var DEFAULT_DESCRIPTION = {
2457
+ forbidden: "This app is limited to one Workspace group.",
2458
+ error: "Something interrupted sign-in. Try again in a moment."
2459
+ };
2460
+ function Spinner({ className }) {
2461
+ return /* @__PURE__ */ jsx49(
2462
+ "span",
2463
+ {
2464
+ "aria-hidden": "true",
2465
+ className: cn(
2466
+ "inline-block animate-spin rounded-full border-2 border-current border-t-transparent",
2467
+ className
2468
+ )
2469
+ }
2470
+ );
2471
+ }
2472
+ function GoogleGlyph() {
2473
+ return /* @__PURE__ */ jsx49("span", { className: "inline-flex size-[26px] flex-none items-center justify-center rounded-md bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.05)_inset]", children: /* @__PURE__ */ jsxs23("svg", { width: "17", height: "17", viewBox: "0 0 18 18", "aria-hidden": "true", children: [
2474
+ /* @__PURE__ */ jsx49("path", { fill: "#4285F4", d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z" }),
2475
+ /* @__PURE__ */ jsx49("path", { fill: "#34A853", d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z" }),
2476
+ /* @__PURE__ */ jsx49("path", { fill: "#FBBC05", d: "M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z" }),
2477
+ /* @__PURE__ */ jsx49("path", { fill: "#EA4335", d: "M9 3.58c1.32 0 2.5.46 3.44 1.35l2.58-2.58C13.46.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z" })
2478
+ ] }) });
2479
+ }
2480
+ var LockIcon = (props) => /* @__PURE__ */ jsxs23("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: [
2481
+ /* @__PURE__ */ jsx49("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2" }),
2482
+ /* @__PURE__ */ jsx49("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
2483
+ ] });
2484
+ var WarningIcon = (props) => /* @__PURE__ */ jsxs23("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: [
2485
+ /* @__PURE__ */ jsx49("path", { d: "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
2486
+ /* @__PURE__ */ jsx49("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
2487
+ /* @__PURE__ */ jsx49("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2488
+ ] });
2489
+ var ErrorIcon = (props) => /* @__PURE__ */ jsxs23("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: [
2490
+ /* @__PURE__ */ jsx49("circle", { cx: "12", cy: "12", r: "10" }),
2491
+ /* @__PURE__ */ jsx49("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2492
+ /* @__PURE__ */ jsx49("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2493
+ ] });
2494
+ var RetryIcon = (props) => /* @__PURE__ */ jsxs23("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: [
2495
+ /* @__PURE__ */ jsx49("path", { d: "M23 4v6h-6" }),
2496
+ /* @__PURE__ */ jsx49("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
2497
+ ] });
2498
+ var filledBtn = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-transparent bg-text-primary px-[14px] text-[14.5px] font-semibold tracking-[-0.005em] text-bg-sunken transition-opacity hover:opacity-[0.92] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand active:translate-y-px disabled:cursor-not-allowed disabled:opacity-[0.55]";
2499
+ var calloutBase = "mb-[22px] flex gap-[10px] rounded-[10px] border px-[13px] py-[12px] text-left text-[13px] leading-[1.5] text-text-secondary [&_code]:font-mono [&_code]:text-[12px] [&_code]:text-text-primary [&_strong]:font-semibold [&_strong]:text-text-primary";
2500
+ function LockNote({ children }) {
2501
+ return /* @__PURE__ */ jsxs23("div", { className: "mx-auto mt-[20px] flex flex-wrap items-center justify-center gap-[7px] text-[12px] leading-[1.4] text-text-secondary [&_code]:rounded-[5px] [&_code]:bg-bg-secondary [&_code]:px-[6px] [&_code]:py-[2px] [&_code]:font-mono [&_code]:text-[11.5px] [&_code]:text-text-secondary", children: [
2502
+ /* @__PURE__ */ jsx49(LockIcon, { className: "flex-none text-text-tertiary" }),
2503
+ children
2504
+ ] });
2505
+ }
2506
+ var SignInScreen = React43.forwardRef(
2507
+ ({
2508
+ state: state2 = "login",
2509
+ brand,
2510
+ eyebrow,
2511
+ title,
2512
+ description,
2513
+ googleLabel = "Continue with Google",
2514
+ onGoogle,
2515
+ signingIn = false,
2516
+ signingInLabel = "Signing you in\u2026",
2517
+ restriction,
2518
+ forbidden,
2519
+ error,
2520
+ onRetry,
2521
+ retryLabel = "Try again",
2522
+ loadingLabel = "Loading\u2026",
2523
+ footer = "Supercharged by Lessly",
2524
+ className,
2525
+ ...props
2526
+ }, ref) => {
2527
+ const shell = (children) => /* @__PURE__ */ jsx49(
2528
+ "div",
2529
+ {
2530
+ ref,
2531
+ className: cn(
2532
+ "relative flex min-h-screen w-full items-center justify-center overflow-hidden px-6 py-12 text-text-primary",
2533
+ className
2534
+ ),
2535
+ style: { background: GLOW_BG },
2536
+ ...props,
2537
+ children
2538
+ }
2539
+ );
2540
+ const brandMark = /* @__PURE__ */ jsx49("div", { className: "text-[24px] font-bold leading-none tracking-[-0.02em] text-text-primary", children: brand });
2541
+ if (state2 === "loading") {
2542
+ return shell(
2543
+ /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-center gap-[16px] text-text-secondary", children: [
2544
+ brandMark,
2545
+ /* @__PURE__ */ jsx49(Spinner, { className: "size-[22px] text-text-tertiary opacity-90" }),
2546
+ /* @__PURE__ */ jsx49("span", { role: "status", className: "text-[13.5px] tracking-[-0.005em]", children: loadingLabel })
2547
+ ] })
2548
+ );
2549
+ }
2550
+ const heading = title ?? DEFAULT_TITLE[state2];
2551
+ const sub = description ?? DEFAULT_DESCRIPTION[state2];
2552
+ return shell(
2553
+ /* @__PURE__ */ jsxs23(
2554
+ "div",
2555
+ {
2556
+ className: "relative w-full max-w-[360px] rounded-2xl bg-bg-surface px-[34px] pb-[30px] pt-[38px] text-center",
2557
+ style: {
2558
+ border: "1px solid var(--auth-card-border)",
2559
+ boxShadow: "var(--auth-card-shadow)"
2560
+ },
2561
+ children: [
2562
+ /* @__PURE__ */ jsx49("div", { className: "mb-[22px]", children: brandMark }),
2563
+ eyebrow && state2 === "login" && /* @__PURE__ */ jsx49("p", { className: "mb-[12px] text-[11px] font-semibold uppercase tracking-[0.11em] text-text-tertiary", children: eyebrow }),
2564
+ /* @__PURE__ */ jsx49("h1", { className: "mb-[8px] text-[20px] font-semibold leading-[1.25] tracking-[-0.015em] text-text-primary", children: heading }),
2565
+ sub && /* @__PURE__ */ jsx49("p", { className: "mx-auto mb-[24px] max-w-[280px] text-[13.5px] leading-[1.5] text-text-secondary", children: sub }),
2566
+ state2 === "login" && /* @__PURE__ */ jsx49(
2567
+ "button",
2568
+ {
2569
+ type: "button",
2570
+ onClick: onGoogle,
2571
+ disabled: signingIn,
2572
+ "aria-busy": signingIn || void 0,
2573
+ className: filledBtn,
2574
+ style: { boxShadow: "var(--auth-btn-shadow)" },
2575
+ children: signingIn ? /* @__PURE__ */ jsxs23(Fragment, { children: [
2576
+ /* @__PURE__ */ jsx49(Spinner, { className: "size-[17px] opacity-50" }),
2577
+ /* @__PURE__ */ jsx49("span", { children: signingInLabel })
2578
+ ] }) : /* @__PURE__ */ jsxs23(Fragment, { children: [
2579
+ /* @__PURE__ */ jsx49(GoogleGlyph, {}),
2580
+ /* @__PURE__ */ jsx49("span", { children: googleLabel })
2581
+ ] })
2582
+ }
2583
+ ),
2584
+ state2 === "forbidden" && forbidden && /* @__PURE__ */ jsxs23("div", { role: "status", className: cn(calloutBase, "border-border-warning bg-bg-warning-subtle"), children: [
2585
+ /* @__PURE__ */ jsx49(WarningIcon, { className: "mt-px flex-none text-border-warning" }),
2586
+ /* @__PURE__ */ jsx49("span", { children: forbidden })
2587
+ ] }),
2588
+ state2 === "error" && /* @__PURE__ */ jsxs23(Fragment, { children: [
2589
+ /* @__PURE__ */ jsxs23("div", { role: "alert", className: cn(calloutBase, "border-border-danger bg-bg-danger-subtle"), children: [
2590
+ /* @__PURE__ */ jsx49(ErrorIcon, { className: "mt-px flex-none text-border-danger" }),
2591
+ /* @__PURE__ */ jsx49("span", { children: error ?? "The identity provider didn\u2019t respond. Retry in a moment." })
2592
+ ] }),
2593
+ onRetry && /* @__PURE__ */ jsxs23(
2594
+ "button",
2595
+ {
2596
+ type: "button",
2597
+ onClick: onRetry,
2598
+ className: filledBtn,
2599
+ style: { boxShadow: "var(--auth-btn-shadow)" },
2600
+ children: [
2601
+ /* @__PURE__ */ jsx49(RetryIcon, {}),
2602
+ /* @__PURE__ */ jsx49("span", { children: retryLabel })
2603
+ ]
2604
+ }
2605
+ )
2606
+ ] }),
2607
+ restriction && (state2 === "login" || state2 === "forbidden") && /* @__PURE__ */ jsx49(LockNote, { children: restriction }),
2608
+ footer != null && /* @__PURE__ */ jsx49("div", { className: "mt-[24px] text-[11px] tracking-[0.005em] text-text-tertiary", children: footer })
2609
+ ]
2610
+ }
2611
+ )
2612
+ );
2613
+ }
2614
+ );
2615
+ SignInScreen.displayName = "SignInScreen";
2616
+
2617
+ // src/components/copy-button.tsx
2618
+ import * as React44 from "react";
2449
2619
  import { Check as Check5, Copy } from "lucide-react";
2450
- import { jsx as jsx49 } from "react/jsx-runtime";
2451
- var CopyButton = React43.forwardRef(
2620
+ import { jsx as jsx50 } from "react/jsx-runtime";
2621
+ var CopyButton = React44.forwardRef(
2452
2622
  ({ value, label = "Copy", className, variant = "ghost", size = "icon", onClick, ...props }, ref) => {
2453
- const [copied, setCopied] = React43.useState(false);
2454
- const timer = React43.useRef(void 0);
2455
- React43.useEffect(() => () => clearTimeout(timer.current), []);
2623
+ const [copied, setCopied] = React44.useState(false);
2624
+ const timer = React44.useRef(void 0);
2625
+ React44.useEffect(() => () => clearTimeout(timer.current), []);
2456
2626
  const handleClick = async (e) => {
2457
2627
  onClick?.(e);
2458
2628
  if (!navigator.clipboard?.writeText) return;
@@ -2464,7 +2634,7 @@ var CopyButton = React43.forwardRef(
2464
2634
  } catch {
2465
2635
  }
2466
2636
  };
2467
- return /* @__PURE__ */ jsx49(
2637
+ return /* @__PURE__ */ jsx50(
2468
2638
  Button,
2469
2639
  {
2470
2640
  ref,
@@ -2475,7 +2645,7 @@ var CopyButton = React43.forwardRef(
2475
2645
  className: cn(className),
2476
2646
  ...props,
2477
2647
  "aria-label": copied ? "Copied" : label,
2478
- children: copied ? /* @__PURE__ */ jsx49(Check5, { className: "size-4 text-text-success" }) : /* @__PURE__ */ jsx49(Copy, { className: "size-4" })
2648
+ children: copied ? /* @__PURE__ */ jsx50(Check5, { className: "size-4 text-text-success" }) : /* @__PURE__ */ jsx50(Copy, { className: "size-4" })
2479
2649
  }
2480
2650
  );
2481
2651
  }
@@ -2483,9 +2653,9 @@ var CopyButton = React43.forwardRef(
2483
2653
  CopyButton.displayName = "CopyButton";
2484
2654
 
2485
2655
  // src/components/stat-card.tsx
2486
- import * as React44 from "react";
2656
+ import * as React45 from "react";
2487
2657
  import { ArrowDown, ArrowUp, Info as Info2, Minus as Minus2 } from "lucide-react";
2488
- import { jsx as jsx50, jsxs as jsxs23 } from "react/jsx-runtime";
2658
+ import { jsx as jsx51, jsxs as jsxs24 } from "react/jsx-runtime";
2489
2659
  var directionIcons = {
2490
2660
  up: ArrowUp,
2491
2661
  down: ArrowDown,
@@ -2501,36 +2671,36 @@ var toneFromDirection = {
2501
2671
  down: "negative",
2502
2672
  neutral: "neutral"
2503
2673
  };
2504
- var StatCard = React44.forwardRef(
2674
+ var StatCard = React45.forwardRef(
2505
2675
  ({ label, value, delta, hint, sub, icon: Icon, className, ...props }, ref) => {
2506
2676
  const direction = delta?.direction ?? "neutral";
2507
2677
  const tone = delta?.tone ?? toneFromDirection[direction];
2508
2678
  const DeltaIcon = directionIcons[direction];
2509
2679
  const deltaClass = toneClasses[tone];
2510
- return /* @__PURE__ */ jsxs23(
2680
+ return /* @__PURE__ */ jsxs24(
2511
2681
  "div",
2512
2682
  {
2513
2683
  ref,
2514
2684
  className: cn("rounded-xl border border-border-subtle bg-bg-surface p-5", className),
2515
2685
  ...props,
2516
2686
  children: [
2517
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between gap-2", children: [
2518
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-1.5", children: [
2519
- /* @__PURE__ */ jsx50("span", { className: "text-xs font-medium uppercase tracking-wide text-text-tertiary", children: label }),
2520
- hint && /* @__PURE__ */ jsx50(TooltipProvider, { children: /* @__PURE__ */ jsxs23(Tooltip, { children: [
2521
- /* @__PURE__ */ jsx50(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx50("button", { type: "button", "aria-label": "More info", className: "inline-flex cursor-help text-icon-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus rounded-sm", children: /* @__PURE__ */ jsx50(Info2, { className: "size-3.5", "aria-hidden": "true" }) }) }),
2522
- /* @__PURE__ */ jsx50(TooltipContent, { children: hint })
2687
+ /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between gap-2", children: [
2688
+ /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5", children: [
2689
+ /* @__PURE__ */ jsx51("span", { className: "text-xs font-medium uppercase tracking-wide text-text-tertiary", children: label }),
2690
+ hint && /* @__PURE__ */ jsx51(TooltipProvider, { children: /* @__PURE__ */ jsxs24(Tooltip, { children: [
2691
+ /* @__PURE__ */ jsx51(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx51("button", { type: "button", "aria-label": "More info", className: "inline-flex cursor-help text-icon-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus rounded-sm", children: /* @__PURE__ */ jsx51(Info2, { className: "size-3.5", "aria-hidden": "true" }) }) }),
2692
+ /* @__PURE__ */ jsx51(TooltipContent, { children: hint })
2523
2693
  ] }) })
2524
2694
  ] }),
2525
- Icon && /* @__PURE__ */ jsx50(Icon, { className: "size-4 text-icon-secondary", "aria-hidden": "true" })
2695
+ Icon && /* @__PURE__ */ jsx51(Icon, { className: "size-4 text-icon-secondary", "aria-hidden": "true" })
2526
2696
  ] }),
2527
- /* @__PURE__ */ jsx50("div", { className: "mt-2 text-3xl font-semibold text-text-primary", children: value }),
2528
- (delta || sub) && /* @__PURE__ */ jsxs23("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [
2529
- delta && /* @__PURE__ */ jsxs23("span", { className: cn("inline-flex items-center gap-0.5 font-medium", deltaClass), children: [
2530
- /* @__PURE__ */ jsx50(DeltaIcon, { className: "size-3.5", "aria-hidden": "true" }),
2697
+ /* @__PURE__ */ jsx51("div", { className: "mt-2 text-3xl font-semibold text-text-primary", children: value }),
2698
+ (delta || sub) && /* @__PURE__ */ jsxs24("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [
2699
+ delta && /* @__PURE__ */ jsxs24("span", { className: cn("inline-flex items-center gap-0.5 font-medium", deltaClass), children: [
2700
+ /* @__PURE__ */ jsx51(DeltaIcon, { className: "size-3.5", "aria-hidden": "true" }),
2531
2701
  delta.value
2532
2702
  ] }),
2533
- sub && /* @__PURE__ */ jsx50("span", { className: "text-text-tertiary", children: sub })
2703
+ sub && /* @__PURE__ */ jsx51("span", { className: "text-text-tertiary", children: sub })
2534
2704
  ] })
2535
2705
  ]
2536
2706
  }
@@ -2540,11 +2710,11 @@ var StatCard = React44.forwardRef(
2540
2710
  StatCard.displayName = "StatCard";
2541
2711
 
2542
2712
  // src/components/confirm-dialog.tsx
2543
- import * as React45 from "react";
2713
+ import * as React46 from "react";
2544
2714
  import { Loader2 } from "lucide-react";
2545
- import { jsx as jsx51, jsxs as jsxs24 } from "react/jsx-runtime";
2546
- var InlineError = React45.forwardRef(
2547
- ({ children, className, ...props }, ref) => /* @__PURE__ */ jsx51(
2715
+ import { jsx as jsx52, jsxs as jsxs25 } from "react/jsx-runtime";
2716
+ var InlineError = React46.forwardRef(
2717
+ ({ children, className, ...props }, ref) => /* @__PURE__ */ jsx52(
2548
2718
  "div",
2549
2719
  {
2550
2720
  ref,
@@ -2570,12 +2740,12 @@ function ConfirmDialog({
2570
2740
  destructive = false,
2571
2741
  onConfirm
2572
2742
  }) {
2573
- const [internalOpen, setInternalOpen] = React45.useState(false);
2743
+ const [internalOpen, setInternalOpen] = React46.useState(false);
2574
2744
  const isControlled = open !== void 0;
2575
2745
  const actualOpen = isControlled ? open : internalOpen;
2576
- const [busy, setBusy] = React45.useState(false);
2577
- const [error, setError] = React45.useState(null);
2578
- React45.useEffect(() => {
2746
+ const [busy, setBusy] = React46.useState(false);
2747
+ const [error, setError] = React46.useState(null);
2748
+ React46.useEffect(() => {
2579
2749
  if (!actualOpen) setError(null);
2580
2750
  }, [actualOpen]);
2581
2751
  const setOpen = (next) => {
@@ -2595,20 +2765,20 @@ function ConfirmDialog({
2595
2765
  setBusy(false);
2596
2766
  }
2597
2767
  };
2598
- return /* @__PURE__ */ jsxs24(Dialog, { open: actualOpen, onOpenChange: (next) => {
2768
+ return /* @__PURE__ */ jsxs25(Dialog, { open: actualOpen, onOpenChange: (next) => {
2599
2769
  if (!busy) setOpen(next);
2600
2770
  }, children: [
2601
- trigger && /* @__PURE__ */ jsx51(DialogTrigger, { asChild: true, children: trigger }),
2602
- /* @__PURE__ */ jsxs24(DialogContent, { children: [
2603
- /* @__PURE__ */ jsxs24(DialogHeader, { children: [
2604
- /* @__PURE__ */ jsx51(DialogTitle, { children: title }),
2605
- description && /* @__PURE__ */ jsx51(DialogDescription, { children: description })
2771
+ trigger && /* @__PURE__ */ jsx52(DialogTrigger, { asChild: true, children: trigger }),
2772
+ /* @__PURE__ */ jsxs25(DialogContent, { children: [
2773
+ /* @__PURE__ */ jsxs25(DialogHeader, { children: [
2774
+ /* @__PURE__ */ jsx52(DialogTitle, { children: title }),
2775
+ description && /* @__PURE__ */ jsx52(DialogDescription, { children: description })
2606
2776
  ] }),
2607
- error && /* @__PURE__ */ jsx51(InlineError, { children: error }),
2608
- /* @__PURE__ */ jsxs24(DialogFooter, { children: [
2609
- /* @__PURE__ */ jsx51(Button, { variant: "outline", disabled: busy, onClick: () => setOpen(false), children: cancelLabel }),
2610
- /* @__PURE__ */ jsxs24(Button, { variant: destructive ? "destructive" : "default", disabled: busy, onClick: handleConfirm, children: [
2611
- busy && /* @__PURE__ */ jsx51(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" }),
2777
+ error && /* @__PURE__ */ jsx52(InlineError, { children: error }),
2778
+ /* @__PURE__ */ jsxs25(DialogFooter, { children: [
2779
+ /* @__PURE__ */ jsx52(Button, { variant: "outline", disabled: busy, onClick: () => setOpen(false), children: cancelLabel }),
2780
+ /* @__PURE__ */ jsxs25(Button, { variant: destructive ? "destructive" : "default", disabled: busy, onClick: handleConfirm, children: [
2781
+ busy && /* @__PURE__ */ jsx52(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" }),
2612
2782
  confirmLabel
2613
2783
  ] })
2614
2784
  ] })
@@ -2618,7 +2788,7 @@ function ConfirmDialog({
2618
2788
 
2619
2789
  // src/components/user-menu.tsx
2620
2790
  import { ChevronsUpDown } from "lucide-react";
2621
- import { Fragment, jsx as jsx52, jsxs as jsxs25 } from "react/jsx-runtime";
2791
+ import { Fragment as Fragment2, jsx as jsx53, jsxs as jsxs26 } from "react/jsx-runtime";
2622
2792
  function initialsOf(name) {
2623
2793
  const parts = name.trim().split(/\s+/).filter(Boolean);
2624
2794
  if (parts.length === 0) return "?";
@@ -2627,11 +2797,11 @@ function initialsOf(name) {
2627
2797
  }
2628
2798
  function UserMenu({ user, items, collapsed = false, align = "start" }) {
2629
2799
  const secondLine = user.subtitle ?? user.email;
2630
- const avatar = /* @__PURE__ */ jsxs25(Avatar, { className: collapsed ? "size-9" : "size-7", children: [
2631
- user.avatarUrl && /* @__PURE__ */ jsx52(AvatarImage, { src: user.avatarUrl, alt: user.name }),
2632
- /* @__PURE__ */ jsx52(AvatarFallback, { className: "text-xs", children: initialsOf(user.name) })
2800
+ const avatar = /* @__PURE__ */ jsxs26(Avatar, { className: collapsed ? "size-9" : "size-7", children: [
2801
+ user.avatarUrl && /* @__PURE__ */ jsx53(AvatarImage, { src: user.avatarUrl, alt: user.name }),
2802
+ /* @__PURE__ */ jsx53(AvatarFallback, { className: "text-xs", children: initialsOf(user.name) })
2633
2803
  ] });
2634
- const trigger = collapsed ? /* @__PURE__ */ jsx52(
2804
+ const trigger = collapsed ? /* @__PURE__ */ jsx53(
2635
2805
  "button",
2636
2806
  {
2637
2807
  type: "button",
@@ -2639,46 +2809,46 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
2639
2809
  className: "rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
2640
2810
  children: avatar
2641
2811
  }
2642
- ) : /* @__PURE__ */ jsxs25(
2812
+ ) : /* @__PURE__ */ jsxs26(
2643
2813
  "button",
2644
2814
  {
2645
2815
  type: "button",
2646
2816
  className: "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-[5px] text-left transition-colors hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
2647
2817
  children: [
2648
2818
  avatar,
2649
- /* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
2650
- /* @__PURE__ */ jsx52("span", { className: "truncate text-sm leading-[normal] font-medium text-text-primary", children: user.name }),
2651
- secondLine && /* @__PURE__ */ jsx52("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: secondLine })
2819
+ /* @__PURE__ */ jsxs26("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
2820
+ /* @__PURE__ */ jsx53("span", { className: "truncate text-sm leading-[normal] font-medium text-text-primary", children: user.name }),
2821
+ secondLine && /* @__PURE__ */ jsx53("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: secondLine })
2652
2822
  ] }),
2653
- /* @__PURE__ */ jsx52(ChevronsUpDown, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
2823
+ /* @__PURE__ */ jsx53(ChevronsUpDown, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
2654
2824
  ]
2655
2825
  }
2656
2826
  );
2657
- const menuTrigger = /* @__PURE__ */ jsx52(DropdownMenuTrigger, { asChild: true, children: trigger });
2658
- const menu = /* @__PURE__ */ jsxs25(DropdownMenu, { children: [
2659
- collapsed ? /* @__PURE__ */ jsx52(TooltipProvider, { children: /* @__PURE__ */ jsxs25(Tooltip, { children: [
2660
- /* @__PURE__ */ jsx52(TooltipTrigger, { asChild: true, children: menuTrigger }),
2661
- /* @__PURE__ */ jsx52(TooltipContent, { side: "right", children: user.name })
2827
+ const menuTrigger = /* @__PURE__ */ jsx53(DropdownMenuTrigger, { asChild: true, children: trigger });
2828
+ const menu = /* @__PURE__ */ jsxs26(DropdownMenu, { children: [
2829
+ collapsed ? /* @__PURE__ */ jsx53(TooltipProvider, { children: /* @__PURE__ */ jsxs26(Tooltip, { children: [
2830
+ /* @__PURE__ */ jsx53(TooltipTrigger, { asChild: true, children: menuTrigger }),
2831
+ /* @__PURE__ */ jsx53(TooltipContent, { side: "right", children: user.name })
2662
2832
  ] }) }) : menuTrigger,
2663
- /* @__PURE__ */ jsxs25(
2833
+ /* @__PURE__ */ jsxs26(
2664
2834
  DropdownMenuContent,
2665
2835
  {
2666
2836
  align,
2667
2837
  sideOffset: 6,
2668
2838
  className: "flex w-56 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
2669
2839
  children: [
2670
- /* @__PURE__ */ jsxs25(DropdownMenuLabel, { className: "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary", children: [
2671
- /* @__PURE__ */ jsx52("span", { className: "block truncate text-sm font-medium text-text-primary", children: user.name }),
2672
- secondLine && /* @__PURE__ */ jsx52("span", { className: "block truncate text-xs font-normal text-text-tertiary", children: secondLine })
2840
+ /* @__PURE__ */ jsxs26(DropdownMenuLabel, { className: "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary", children: [
2841
+ /* @__PURE__ */ jsx53("span", { className: "block truncate text-sm font-medium text-text-primary", children: user.name }),
2842
+ secondLine && /* @__PURE__ */ jsx53("span", { className: "block truncate text-xs font-normal text-text-tertiary", children: secondLine })
2673
2843
  ] }),
2674
- /* @__PURE__ */ jsx52(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
2844
+ /* @__PURE__ */ jsx53(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
2675
2845
  items.map((item, i) => {
2676
2846
  const Icon = item.icon;
2677
- const content = /* @__PURE__ */ jsxs25(Fragment, { children: [
2678
- Icon && /* @__PURE__ */ jsx52(Icon, { className: "size-4", "aria-hidden": "true" }),
2847
+ const content = /* @__PURE__ */ jsxs26(Fragment2, { children: [
2848
+ Icon && /* @__PURE__ */ jsx53(Icon, { className: "size-4", "aria-hidden": "true" }),
2679
2849
  item.label
2680
2850
  ] });
2681
- return /* @__PURE__ */ jsx52(
2851
+ return /* @__PURE__ */ jsx53(
2682
2852
  DropdownMenuItem,
2683
2853
  {
2684
2854
  onSelect: item.onSelect,
@@ -2687,7 +2857,7 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
2687
2857
  item.destructive && "text-text-danger focus:text-text-danger"
2688
2858
  ),
2689
2859
  asChild: Boolean(item.href),
2690
- children: item.href ? /* @__PURE__ */ jsx52("a", { href: item.href, children: content }) : content
2860
+ children: item.href ? /* @__PURE__ */ jsx53("a", { href: item.href, children: content }) : content
2691
2861
  },
2692
2862
  `${item.label}-${i}`
2693
2863
  );
@@ -2701,20 +2871,20 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
2701
2871
 
2702
2872
  // src/components/extension-link.tsx
2703
2873
  import { Link as Link2 } from "react-router";
2704
- import { jsx as jsx53 } from "react/jsx-runtime";
2874
+ import { jsx as jsx54 } from "react/jsx-runtime";
2705
2875
  function ExtensionLink({ uiMode, to, className, children, ...anchorProps }) {
2706
2876
  if (uiMode === "federation") {
2707
- return /* @__PURE__ */ jsx53(Link2, { to, className, ...anchorProps, children });
2877
+ return /* @__PURE__ */ jsx54(Link2, { to, className, ...anchorProps, children });
2708
2878
  }
2709
- return /* @__PURE__ */ jsx53("a", { href: to, className, ...anchorProps, children });
2879
+ return /* @__PURE__ */ jsx54("a", { href: to, className, ...anchorProps, children });
2710
2880
  }
2711
2881
  ExtensionLink.displayName = "ExtensionLink";
2712
2882
 
2713
2883
  // src/components/extension-icon.tsx
2714
- import * as React46 from "react";
2884
+ import * as React47 from "react";
2715
2885
  import * as LucideIcons from "lucide-react";
2716
2886
  import { Puzzle } from "lucide-react";
2717
- import { jsx as jsx54 } from "react/jsx-runtime";
2887
+ import { jsx as jsx55 } from "react/jsx-runtime";
2718
2888
  var FORWARD_REF = /* @__PURE__ */ Symbol.for("react.forward_ref");
2719
2889
  var catalog = LucideIcons;
2720
2890
  function toPascalCase(name) {
@@ -2739,14 +2909,14 @@ function warnUnknownIconOnce(name) {
2739
2909
  warnedUnknownIcons.add(name);
2740
2910
  console.warn(`[@lessly/ui] ExtensionIcon: unknown icon "${name}" \u2014 falling back to Puzzle.`);
2741
2911
  }
2742
- var ExtensionIcon = React46.forwardRef(
2912
+ var ExtensionIcon = React47.forwardRef(
2743
2913
  ({ name, ...props }, ref) => {
2744
2914
  const Icon = resolveIcon(name);
2745
2915
  if (!Icon) {
2746
2916
  warnUnknownIconOnce(name);
2747
- return /* @__PURE__ */ jsx54(Puzzle, { ref, ...props });
2917
+ return /* @__PURE__ */ jsx55(Puzzle, { ref, ...props });
2748
2918
  }
2749
- return /* @__PURE__ */ jsx54(Icon, { ref, ...props });
2919
+ return /* @__PURE__ */ jsx55(Icon, { ref, ...props });
2750
2920
  }
2751
2921
  );
2752
2922
  ExtensionIcon.displayName = "ExtensionIcon";
@@ -2793,9 +2963,9 @@ function useSidebar(options = {}) {
2793
2963
  }
2794
2964
 
2795
2965
  // src/components/nav-row.tsx
2796
- import * as React47 from "react";
2966
+ import * as React48 from "react";
2797
2967
  import { Slot as Slot4 } from "@radix-ui/react-slot";
2798
- import { Fragment as Fragment2, jsx as jsx55, jsxs as jsxs26 } from "react/jsx-runtime";
2968
+ import { Fragment as Fragment3, jsx as jsx56, jsxs as jsxs27 } from "react/jsx-runtime";
2799
2969
  var base = "flex w-full items-center text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
2800
2970
  var shape = {
2801
2971
  rail: "gap-[14px] rounded-xl px-2.5 py-2",
@@ -2811,9 +2981,9 @@ var state = {
2811
2981
  active: "font-semibold text-text-brand hover:bg-[var(--menu-hov)]"
2812
2982
  }
2813
2983
  };
2814
- var NavRow = React47.forwardRef(function NavRow2({ icon, label, active = false, variant, trailing, hideLabel = false, asChild = false, className, children, ...props }, ref) {
2815
- const content = /* @__PURE__ */ jsxs26(Fragment2, { children: [
2816
- icon && /* @__PURE__ */ jsx55(
2984
+ var NavRow = React48.forwardRef(function NavRow2({ icon, label, active = false, variant, trailing, hideLabel = false, asChild = false, className, children, ...props }, ref) {
2985
+ const content = /* @__PURE__ */ jsxs27(Fragment3, { children: [
2986
+ icon && /* @__PURE__ */ jsx56(
2817
2987
  "span",
2818
2988
  {
2819
2989
  className: "flex size-5 shrink-0 items-center justify-center [&_svg]:size-[18px]",
@@ -2821,24 +2991,24 @@ var NavRow = React47.forwardRef(function NavRow2({ icon, label, active = false,
2821
2991
  children: icon
2822
2992
  }
2823
2993
  ),
2824
- !hideLabel && /* @__PURE__ */ jsx55("span", { className: "min-w-0 flex-1 truncate", children: label }),
2825
- trailing && /* @__PURE__ */ jsx55("span", { className: "flex shrink-0 items-center", children: trailing })
2994
+ !hideLabel && /* @__PURE__ */ jsx56("span", { className: "min-w-0 flex-1 truncate", children: label }),
2995
+ trailing && /* @__PURE__ */ jsx56("span", { className: "flex shrink-0 items-center", children: trailing })
2826
2996
  ] });
2827
2997
  const classes = cn(base, shape[variant], state[variant][active ? "active" : "idle"], className);
2828
2998
  if (asChild) {
2829
- const child = React47.Children.only(children);
2830
- return /* @__PURE__ */ jsx55(Slot4, { ref, className: classes, "aria-label": hideLabel ? label : void 0, ...props, children: React47.cloneElement(child, void 0, content) });
2999
+ const child = React48.Children.only(children);
3000
+ return /* @__PURE__ */ jsx56(Slot4, { ref, className: classes, "aria-label": hideLabel ? label : void 0, ...props, children: React48.cloneElement(child, void 0, content) });
2831
3001
  }
2832
- return /* @__PURE__ */ jsx55("button", { ref, type: "button", className: classes, "aria-label": hideLabel ? label : void 0, ...props, children: content });
3002
+ return /* @__PURE__ */ jsx56("button", { ref, type: "button", className: classes, "aria-label": hideLabel ? label : void 0, ...props, children: content });
2833
3003
  });
2834
3004
  NavRow.displayName = "NavRow";
2835
3005
 
2836
3006
  // src/components/nav-section-label.tsx
2837
- import * as React48 from "react";
2838
- import { jsx as jsx56 } from "react/jsx-runtime";
2839
- var NavSectionLabel = React48.forwardRef(
3007
+ import * as React49 from "react";
3008
+ import { jsx as jsx57 } from "react/jsx-runtime";
3009
+ var NavSectionLabel = React49.forwardRef(
2840
3010
  function NavSectionLabel2({ className, ...props }, ref) {
2841
- return /* @__PURE__ */ jsx56(
3011
+ return /* @__PURE__ */ jsx57(
2842
3012
  "div",
2843
3013
  {
2844
3014
  ref,
@@ -2851,8 +3021,8 @@ var NavSectionLabel = React48.forwardRef(
2851
3021
  NavSectionLabel.displayName = "NavSectionLabel";
2852
3022
 
2853
3023
  // src/components/menu-popup.tsx
2854
- import * as React49 from "react";
2855
- import { jsx as jsx57, jsxs as jsxs27 } from "react/jsx-runtime";
3024
+ import * as React50 from "react";
3025
+ import { jsx as jsx58, jsxs as jsxs28 } from "react/jsx-runtime";
2856
3026
  function MenuPopup({
2857
3027
  trigger,
2858
3028
  children,
@@ -2864,9 +3034,9 @@ function MenuPopup({
2864
3034
  sideOffset = 6,
2865
3035
  className
2866
3036
  }) {
2867
- return /* @__PURE__ */ jsxs27(Popover, { open, defaultOpen, onOpenChange, children: [
2868
- /* @__PURE__ */ jsx57(PopoverTrigger, { asChild: true, children: trigger }),
2869
- /* @__PURE__ */ jsx57(
3037
+ return /* @__PURE__ */ jsxs28(Popover, { open, defaultOpen, onOpenChange, children: [
3038
+ /* @__PURE__ */ jsx58(PopoverTrigger, { asChild: true, children: trigger }),
3039
+ /* @__PURE__ */ jsx58(
2870
3040
  PopoverContent,
2871
3041
  {
2872
3042
  side: direction === "up" ? "top" : "bottom",
@@ -2881,9 +3051,9 @@ function MenuPopup({
2881
3051
  )
2882
3052
  ] });
2883
3053
  }
2884
- var MenuDivider = React49.forwardRef(
3054
+ var MenuDivider = React50.forwardRef(
2885
3055
  function MenuDivider2({ className, ...props }, ref) {
2886
- return /* @__PURE__ */ jsx57(
3056
+ return /* @__PURE__ */ jsx58(
2887
3057
  "div",
2888
3058
  {
2889
3059
  ref,
@@ -2898,7 +3068,7 @@ MenuDivider.displayName = "MenuDivider";
2898
3068
 
2899
3069
  // src/components/sidebar-nav.tsx
2900
3070
  import { Link as Link3, useLocation } from "react-router";
2901
- import { jsx as jsx58, jsxs as jsxs28 } from "react/jsx-runtime";
3071
+ import { jsx as jsx59, jsxs as jsxs29 } from "react/jsx-runtime";
2902
3072
  function isActivePath(pathname, full, exact) {
2903
3073
  if (exact) return pathname === full;
2904
3074
  return pathname === full || pathname.startsWith(`${full}/`);
@@ -2914,23 +3084,23 @@ function SidebarNavLink({
2914
3084
  const Comp = LinkComponent ?? Link3;
2915
3085
  const to = `${basePath}${item.href}`;
2916
3086
  const Icon = item.icon;
2917
- const link = /* @__PURE__ */ jsx58(
3087
+ const link = /* @__PURE__ */ jsx59(
2918
3088
  NavRow,
2919
3089
  {
2920
3090
  variant: "rail",
2921
3091
  active,
2922
3092
  label: item.label,
2923
3093
  hideLabel: collapsed,
2924
- icon: Icon ? /* @__PURE__ */ jsx58(Icon, { "aria-hidden": "true" }) : void 0,
3094
+ icon: Icon ? /* @__PURE__ */ jsx59(Icon, { "aria-hidden": "true" }) : void 0,
2925
3095
  className: cn(collapsed && "size-9 justify-center px-0 py-0", className),
2926
3096
  asChild: true,
2927
- children: /* @__PURE__ */ jsx58(Comp, { to, "aria-current": active ? "page" : void 0 })
3097
+ children: /* @__PURE__ */ jsx59(Comp, { to, "aria-current": active ? "page" : void 0 })
2928
3098
  }
2929
3099
  );
2930
3100
  if (!collapsed) return link;
2931
- return /* @__PURE__ */ jsxs28(Tooltip, { children: [
2932
- /* @__PURE__ */ jsx58(TooltipTrigger, { asChild: true, children: link }),
2933
- /* @__PURE__ */ jsx58(TooltipContent, { side: "right", children: item.label })
3101
+ return /* @__PURE__ */ jsxs29(Tooltip, { children: [
3102
+ /* @__PURE__ */ jsx59(TooltipTrigger, { asChild: true, children: link }),
3103
+ /* @__PURE__ */ jsx59(TooltipContent, { side: "right", children: item.label })
2934
3104
  ] });
2935
3105
  }
2936
3106
  function SidebarNav({
@@ -2942,7 +3112,7 @@ function SidebarNav({
2942
3112
  className
2943
3113
  }) {
2944
3114
  const { pathname } = useLocation();
2945
- const nav = /* @__PURE__ */ jsx58(
3115
+ const nav = /* @__PURE__ */ jsx59(
2946
3116
  "nav",
2947
3117
  {
2948
3118
  className: cn(
@@ -2953,7 +3123,7 @@ function SidebarNav({
2953
3123
  children: items.map((item) => {
2954
3124
  const full = `${basePath}${item.href}`;
2955
3125
  const active = isItemActive ? isItemActive(item, pathname) : isActivePath(pathname, full, item.exact);
2956
- return /* @__PURE__ */ jsx58(
3126
+ return /* @__PURE__ */ jsx59(
2957
3127
  SidebarNavLink,
2958
3128
  {
2959
3129
  item,
@@ -2967,14 +3137,14 @@ function SidebarNav({
2967
3137
  })
2968
3138
  }
2969
3139
  );
2970
- return collapsed ? /* @__PURE__ */ jsx58(TooltipProvider, { children: nav }) : nav;
3140
+ return collapsed ? /* @__PURE__ */ jsx59(TooltipProvider, { children: nav }) : nav;
2971
3141
  }
2972
3142
 
2973
3143
  // src/components/app-sidebar.tsx
2974
3144
  import { PanelLeft } from "lucide-react";
2975
- import { Fragment as Fragment3, jsx as jsx59, jsxs as jsxs29 } from "react/jsx-runtime";
3145
+ import { Fragment as Fragment4, jsx as jsx60, jsxs as jsxs30 } from "react/jsx-runtime";
2976
3146
  function Divider({ collapsed, testId, className }) {
2977
- return /* @__PURE__ */ jsx59(
3147
+ return /* @__PURE__ */ jsx60(
2978
3148
  "div",
2979
3149
  {
2980
3150
  "data-testid": testId,
@@ -3006,7 +3176,7 @@ function AppSidebar({
3006
3176
  defaultCollapsed,
3007
3177
  onCollapsedChange
3008
3178
  });
3009
- const pin = collapsible ? /* @__PURE__ */ jsx59(
3179
+ const pin = collapsible ? /* @__PURE__ */ jsx60(
3010
3180
  "button",
3011
3181
  {
3012
3182
  type: "button",
@@ -3014,10 +3184,10 @@ function AppSidebar({
3014
3184
  "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
3015
3185
  "aria-expanded": !collapsed,
3016
3186
  className: "flex size-6 shrink-0 items-center justify-center rounded-md text-text-secondary transition-colors hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
3017
- children: /* @__PURE__ */ jsx59(PanelLeft, { className: "size-4", "aria-hidden": "true" })
3187
+ children: /* @__PURE__ */ jsx60(PanelLeft, { className: "size-4", "aria-hidden": "true" })
3018
3188
  }
3019
3189
  ) : null;
3020
- return /* @__PURE__ */ jsxs29(
3190
+ return /* @__PURE__ */ jsxs30(
3021
3191
  "aside",
3022
3192
  {
3023
3193
  "data-collapsed": collapsed,
@@ -3027,12 +3197,12 @@ function AppSidebar({
3027
3197
  className
3028
3198
  ),
3029
3199
  children: [
3030
- /* @__PURE__ */ jsx59("div", { className: cn("flex items-center gap-2", collapsed ? "justify-center px-1 pt-2" : "px-3 pt-[13px]"), children: collapsed ? collapsible ? logoCollapsed ?? logo ? (
3200
+ /* @__PURE__ */ jsx60("div", { className: cn("flex items-center gap-2", collapsed ? "justify-center px-1 pt-2" : "px-3 pt-[13px]"), children: collapsed ? collapsible ? logoCollapsed ?? logo ? (
3031
3201
  /* The collapsed rail (52px) can't fit the logo mark beside the pin side by side —
3032
3202
  so the pin overlays the mark instead, revealed on hover/focus, same as pre-flat-rail. */
3033
- /* @__PURE__ */ jsxs29("div", { className: "group relative flex size-8 items-center justify-center", children: [
3034
- /* @__PURE__ */ jsx59("span", { className: "pointer-events-none transition-opacity group-hover:opacity-0 group-focus-within:opacity-0", children: logoCollapsed ?? logo }),
3035
- /* @__PURE__ */ jsx59(
3203
+ /* @__PURE__ */ jsxs30("div", { className: "group relative flex size-8 items-center justify-center", children: [
3204
+ /* @__PURE__ */ jsx60("span", { className: "pointer-events-none transition-opacity group-hover:opacity-0 group-focus-within:opacity-0", children: logoCollapsed ?? logo }),
3205
+ /* @__PURE__ */ jsx60(
3036
3206
  "button",
3037
3207
  {
3038
3208
  type: "button",
@@ -3040,7 +3210,7 @@ function AppSidebar({
3040
3210
  "aria-label": "Expand sidebar",
3041
3211
  "aria-expanded": false,
3042
3212
  className: "absolute inset-0 flex items-center justify-center rounded-md text-text-secondary opacity-0 transition-opacity hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-border-focus group-hover:opacity-100 group-focus-within:opacity-100",
3043
- children: /* @__PURE__ */ jsx59(PanelLeft, { className: "size-4", "aria-hidden": "true" })
3213
+ children: /* @__PURE__ */ jsx60(PanelLeft, { className: "size-4", "aria-hidden": "true" })
3044
3214
  }
3045
3215
  )
3046
3216
  ] })
@@ -3049,7 +3219,7 @@ function AppSidebar({
3049
3219
  count, it's expanded-only). Hover-revealing the pin over nothing would leave
3050
3220
  an invisible 32px box as the only way back to expanded, so render it plain
3051
3221
  and fully visible instead. */
3052
- /* @__PURE__ */ jsx59(
3222
+ /* @__PURE__ */ jsx60(
3053
3223
  "button",
3054
3224
  {
3055
3225
  type: "button",
@@ -3057,15 +3227,15 @@ function AppSidebar({
3057
3227
  "aria-label": "Expand sidebar",
3058
3228
  "aria-expanded": false,
3059
3229
  className: "flex size-8 shrink-0 items-center justify-center rounded-md text-text-secondary transition-colors hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
3060
- children: /* @__PURE__ */ jsx59(PanelLeft, { className: "size-4", "aria-hidden": "true" })
3230
+ children: /* @__PURE__ */ jsx60(PanelLeft, { className: "size-4", "aria-hidden": "true" })
3061
3231
  }
3062
3232
  )
3063
- ) : logoCollapsed ?? logo : /* @__PURE__ */ jsxs29(Fragment3, { children: [
3233
+ ) : logoCollapsed ?? logo : /* @__PURE__ */ jsxs30(Fragment4, { children: [
3064
3234
  header ?? logo,
3065
3235
  pin
3066
3236
  ] }) }),
3067
- /* @__PURE__ */ jsx59(Divider, { collapsed, testId: "sidebar-divider-header", className: "mt-3" }),
3068
- /* @__PURE__ */ jsx59(
3237
+ /* @__PURE__ */ jsx60(Divider, { collapsed, testId: "sidebar-divider-header", className: "mt-3" }),
3238
+ /* @__PURE__ */ jsx60(
3069
3239
  "div",
3070
3240
  {
3071
3241
  "data-testid": "sidebar-scroll",
@@ -3073,12 +3243,12 @@ function AppSidebar({
3073
3243
  "min-h-0 flex-1 overflow-y-auto overflow-x-hidden pt-3 pb-2",
3074
3244
  collapsed ? "px-1" : "px-3"
3075
3245
  ),
3076
- children: /* @__PURE__ */ jsx59(SidebarNav, { items, collapsed, basePath, LinkComponent, isItemActive })
3246
+ children: /* @__PURE__ */ jsx60(SidebarNav, { items, collapsed, basePath, LinkComponent, isItemActive })
3077
3247
  }
3078
3248
  ),
3079
- footer && /* @__PURE__ */ jsxs29(Fragment3, { children: [
3080
- /* @__PURE__ */ jsx59(Divider, { collapsed, testId: "sidebar-divider-account" }),
3081
- /* @__PURE__ */ jsx59("div", { className: cn("py-2", collapsed ? "px-1" : "px-3"), children: footer })
3249
+ footer && /* @__PURE__ */ jsxs30(Fragment4, { children: [
3250
+ /* @__PURE__ */ jsx60(Divider, { collapsed, testId: "sidebar-divider-account" }),
3251
+ /* @__PURE__ */ jsx60("div", { className: cn("py-2", collapsed ? "px-1" : "px-3"), children: footer })
3082
3252
  ] })
3083
3253
  ]
3084
3254
  }
@@ -3086,36 +3256,123 @@ function AppSidebar({
3086
3256
  }
3087
3257
 
3088
3258
  // src/components/sidebar-product-header.tsx
3089
- import * as React50 from "react";
3259
+ import * as React51 from "react";
3090
3260
  import { Slot as Slot5 } from "@radix-ui/react-slot";
3091
3261
  import { ChevronsUpDown as ChevronsUpDown2 } from "lucide-react";
3092
- import { Fragment as Fragment4, jsx as jsx60, jsxs as jsxs30 } from "react/jsx-runtime";
3093
- var SidebarProductHeader = React50.forwardRef(
3262
+ import { Fragment as Fragment5, jsx as jsx61, jsxs as jsxs31 } from "react/jsx-runtime";
3263
+ var SidebarProductHeader = React51.forwardRef(
3094
3264
  function SidebarProductHeader2({ name, icon, trailing, asChild = false, className, children, ...props }, ref) {
3095
- const adornment = trailing === void 0 ? /* @__PURE__ */ jsx60(ChevronsUpDown2, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }) : trailing;
3096
- const content = /* @__PURE__ */ jsxs30(Fragment4, { children: [
3097
- icon && /* @__PURE__ */ jsx60("span", { className: "flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md", "aria-hidden": "true", children: icon }),
3098
- /* @__PURE__ */ jsx60("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-text-primary", children: name }),
3099
- adornment && /* @__PURE__ */ jsx60("span", { className: "flex shrink-0 items-center", children: adornment })
3265
+ const adornment = trailing === void 0 ? /* @__PURE__ */ jsx61(ChevronsUpDown2, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }) : trailing;
3266
+ const content = /* @__PURE__ */ jsxs31(Fragment5, { children: [
3267
+ icon && /* @__PURE__ */ jsx61("span", { className: "flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md", "aria-hidden": "true", children: icon }),
3268
+ /* @__PURE__ */ jsx61("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-text-primary", children: name }),
3269
+ adornment && /* @__PURE__ */ jsx61("span", { className: "flex shrink-0 items-center", children: adornment })
3100
3270
  ] });
3101
3271
  const classes = cn("flex w-full items-center gap-2.5 rounded-xl px-1.5 py-0 text-left", className);
3102
3272
  if (asChild) {
3103
- const child = React50.Children.only(children);
3104
- return /* @__PURE__ */ jsx60(Slot5, { ref, className: classes, ...props, children: React50.cloneElement(child, void 0, content) });
3273
+ const child = React51.Children.only(children);
3274
+ return /* @__PURE__ */ jsx61(Slot5, { ref, className: classes, ...props, children: React51.cloneElement(child, void 0, content) });
3105
3275
  }
3106
- return /* @__PURE__ */ jsx60("button", { ref, type: "button", className: classes, ...props, children: content });
3276
+ return /* @__PURE__ */ jsx61("button", { ref, type: "button", className: classes, ...props, children: content });
3107
3277
  }
3108
3278
  );
3109
3279
  SidebarProductHeader.displayName = "SidebarProductHeader";
3110
3280
 
3281
+ // src/components/org-product-switcher.tsx
3282
+ import { ChevronsUpDown as ChevronsUpDown3, Check as Check6 } from "lucide-react";
3283
+ import { Fragment as Fragment6, jsx as jsx62, jsxs as jsxs32 } from "react/jsx-runtime";
3284
+ var triggerBox = "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-1 text-left transition-colors hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
3285
+ var menuItem = "gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-text-secondary focus:bg-[var(--menu-hov)] focus:text-text-primary";
3286
+ var sectionLabel = "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary";
3287
+ function Mark({ item, size }) {
3288
+ const box = size === "md" ? "size-7" : "size-5";
3289
+ if (item.icon) {
3290
+ return /* @__PURE__ */ jsx62("span", { className: cn("flex shrink-0 items-center justify-center overflow-hidden rounded-md", box), "aria-hidden": "true", children: item.icon });
3291
+ }
3292
+ return /* @__PURE__ */ jsx62(
3293
+ "span",
3294
+ {
3295
+ "aria-hidden": "true",
3296
+ className: cn(
3297
+ "flex shrink-0 items-center justify-center rounded-md bg-[var(--menu-hov)] font-semibold text-text-secondary",
3298
+ box,
3299
+ size === "md" ? "text-sm" : "text-xs"
3300
+ ),
3301
+ children: item.name.charAt(0).toUpperCase()
3302
+ }
3303
+ );
3304
+ }
3305
+ function OrgProductSwitcher({
3306
+ organizations,
3307
+ activeOrgId,
3308
+ onOrgSelect,
3309
+ products,
3310
+ activeProductId,
3311
+ onProductSelect,
3312
+ actions,
3313
+ className,
3314
+ ...props
3315
+ }) {
3316
+ const activeOrg = organizations.find((o) => o.id === activeOrgId);
3317
+ const activeProduct = products.find((p) => p.id === activeProductId);
3318
+ const ariaLabel = props["aria-label"] ?? `${activeOrg?.name ?? ""} / ${activeProduct?.name ?? ""}`;
3319
+ return /* @__PURE__ */ jsxs32(DropdownMenu, { children: [
3320
+ /* @__PURE__ */ jsxs32(DropdownMenuTrigger, { "aria-label": ariaLabel, className: cn(triggerBox, className), children: [
3321
+ activeProduct && /* @__PURE__ */ jsx62(Mark, { item: activeProduct, size: "md" }),
3322
+ /* @__PURE__ */ jsxs32("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
3323
+ /* @__PURE__ */ jsx62("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: activeOrg?.name }),
3324
+ /* @__PURE__ */ jsx62("span", { className: "truncate text-sm leading-[normal] font-semibold text-text-primary", children: activeProduct?.name })
3325
+ ] }),
3326
+ /* @__PURE__ */ jsx62(ChevronsUpDown3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
3327
+ ] }),
3328
+ /* @__PURE__ */ jsxs32(
3329
+ DropdownMenuContent,
3330
+ {
3331
+ align: "start",
3332
+ sideOffset: 6,
3333
+ className: "flex w-60 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
3334
+ children: [
3335
+ /* @__PURE__ */ jsx62(DropdownMenuLabel, { className: sectionLabel, children: "Organizations" }),
3336
+ organizations.map((o) => /* @__PURE__ */ jsxs32(DropdownMenuItem, { className: menuItem, onSelect: () => onOrgSelect(o.id), children: [
3337
+ /* @__PURE__ */ jsx62(Mark, { item: o, size: "sm" }),
3338
+ /* @__PURE__ */ jsx62("span", { className: "min-w-0 flex-1 truncate", children: o.name }),
3339
+ o.id === activeOrgId && /* @__PURE__ */ jsx62(Check6, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
3340
+ ] }, o.id)),
3341
+ /* @__PURE__ */ jsx62(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
3342
+ /* @__PURE__ */ jsxs32(DropdownMenuLabel, { className: sectionLabel, children: [
3343
+ activeOrg?.name,
3344
+ " \xB7 Products"
3345
+ ] }),
3346
+ products.map((p) => /* @__PURE__ */ jsxs32(DropdownMenuItem, { className: menuItem, onSelect: () => onProductSelect(p.id), children: [
3347
+ /* @__PURE__ */ jsx62(Mark, { item: p, size: "sm" }),
3348
+ /* @__PURE__ */ jsx62("span", { className: "min-w-0 flex-1 truncate", children: p.name }),
3349
+ p.id === activeProductId && /* @__PURE__ */ jsx62(Check6, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
3350
+ ] }, p.id)),
3351
+ actions && actions.length > 0 && /* @__PURE__ */ jsxs32(Fragment6, { children: [
3352
+ /* @__PURE__ */ jsx62(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
3353
+ actions.map((a) => /* @__PURE__ */ jsx62(DropdownMenuItem, { className: menuItem, onSelect: a.onSelect, asChild: Boolean(a.href), children: a.href ? /* @__PURE__ */ jsxs32("a", { href: a.href, children: [
3354
+ a.icon,
3355
+ a.label
3356
+ ] }) : /* @__PURE__ */ jsxs32(Fragment6, { children: [
3357
+ a.icon,
3358
+ a.label
3359
+ ] }) }, a.id))
3360
+ ] })
3361
+ ]
3362
+ }
3363
+ )
3364
+ ] });
3365
+ }
3366
+ OrgProductSwitcher.displayName = "OrgProductSwitcher";
3367
+
3111
3368
  // src/components/sidebar-back-header.tsx
3112
3369
  import { ArrowLeft as ArrowLeft2 } from "lucide-react";
3113
- import { jsx as jsx61, jsxs as jsxs31 } from "react/jsx-runtime";
3370
+ import { jsx as jsx63, jsxs as jsxs33 } from "react/jsx-runtime";
3114
3371
  var focusRing = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
3115
3372
  var arrowPlate = "flex size-5 items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--text-primary)_12%,transparent)] hover:text-text-primary";
3116
3373
  var arrowBox = "flex shrink-0 cursor-pointer items-center rounded-xl py-2 pr-0 pl-2.5 text-text-secondary";
3117
3374
  var titleBox = "min-w-0 flex-1 cursor-pointer truncate rounded-xl py-2 pr-2.5 pl-[14px] text-left text-sm font-semibold text-text-primary";
3118
- var Arrow = () => /* @__PURE__ */ jsx61(ArrowLeft2, { size: 16, "aria-hidden": "true" });
3375
+ var Arrow = () => /* @__PURE__ */ jsx63(ArrowLeft2, { size: 16, "aria-hidden": "true" });
3119
3376
  function SidebarBackHeader({
3120
3377
  title,
3121
3378
  onBack,
@@ -3129,7 +3386,7 @@ function SidebarBackHeader({
3129
3386
  const { className: arrowClassName, ...arrowRest } = arrowProps ?? {};
3130
3387
  const { className: titleClassName, ...titleRest } = titleProps ?? {};
3131
3388
  if (!onTitleClick) {
3132
- return /* @__PURE__ */ jsxs31(
3389
+ return /* @__PURE__ */ jsxs33(
3133
3390
  "button",
3134
3391
  {
3135
3392
  type: "button",
@@ -3137,14 +3394,14 @@ function SidebarBackHeader({
3137
3394
  className: cn("flex items-center rounded-xl", focusRing, className),
3138
3395
  ...rowProps,
3139
3396
  children: [
3140
- /* @__PURE__ */ jsx61("span", { className: arrowBox, children: /* @__PURE__ */ jsx61("span", { className: cn(arrowPlate, arrowClassName), ...arrowRest, children: /* @__PURE__ */ jsx61(Arrow, {}) }) }),
3141
- /* @__PURE__ */ jsx61("span", { className: cn(titleBox, titleClassName), ...titleRest, children: title })
3397
+ /* @__PURE__ */ jsx63("span", { className: arrowBox, children: /* @__PURE__ */ jsx63("span", { className: cn(arrowPlate, arrowClassName), ...arrowRest, children: /* @__PURE__ */ jsx63(Arrow, {}) }) }),
3398
+ /* @__PURE__ */ jsx63("span", { className: cn(titleBox, titleClassName), ...titleRest, children: title })
3142
3399
  ]
3143
3400
  }
3144
3401
  );
3145
3402
  }
3146
- return /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center", className), ...rowProps, children: [
3147
- /* @__PURE__ */ jsx61(
3403
+ return /* @__PURE__ */ jsxs33("div", { className: cn("flex items-center", className), ...rowProps, children: [
3404
+ /* @__PURE__ */ jsx63(
3148
3405
  "button",
3149
3406
  {
3150
3407
  type: "button",
@@ -3152,10 +3409,10 @@ function SidebarBackHeader({
3152
3409
  onClick: onBack,
3153
3410
  className: cn(arrowBox, focusRing, arrowClassName),
3154
3411
  ...arrowRest,
3155
- children: /* @__PURE__ */ jsx61("span", { className: arrowPlate, children: /* @__PURE__ */ jsx61(Arrow, {}) })
3412
+ children: /* @__PURE__ */ jsx63("span", { className: arrowPlate, children: /* @__PURE__ */ jsx63(Arrow, {}) })
3156
3413
  }
3157
3414
  ),
3158
- /* @__PURE__ */ jsx61(
3415
+ /* @__PURE__ */ jsx63(
3159
3416
  "button",
3160
3417
  {
3161
3418
  type: "button",
@@ -3170,54 +3427,54 @@ function SidebarBackHeader({
3170
3427
  SidebarBackHeader.displayName = "SidebarBackHeader";
3171
3428
 
3172
3429
  // src/components/app-shell.tsx
3173
- import * as React51 from "react";
3430
+ import * as React52 from "react";
3174
3431
  import { Menu as Menu2 } from "lucide-react";
3175
3432
  import { useLocation as useLocation2 } from "react-router";
3176
- import { jsx as jsx62, jsxs as jsxs32 } from "react/jsx-runtime";
3433
+ import { jsx as jsx64, jsxs as jsxs34 } from "react/jsx-runtime";
3177
3434
  function expandedSidebar(sidebar) {
3178
- return React51.isValidElement(sidebar) ? React51.cloneElement(sidebar, { collapsed: false }) : sidebar;
3435
+ return React52.isValidElement(sidebar) ? React52.cloneElement(sidebar, { collapsed: false }) : sidebar;
3179
3436
  }
3180
3437
  function AppShell({ sidebar, topBar, children, className }) {
3181
3438
  const { pathname } = useLocation2();
3182
- const [mobileOpen, setMobileOpen] = React51.useState(false);
3183
- React51.useEffect(() => {
3439
+ const [mobileOpen, setMobileOpen] = React52.useState(false);
3440
+ React52.useEffect(() => {
3184
3441
  setMobileOpen(false);
3185
3442
  }, [pathname]);
3186
3443
  const isMobile = useIsMobile();
3187
3444
  if (isMobile) {
3188
- return /* @__PURE__ */ jsx62(TooltipProvider, { children: /* @__PURE__ */ jsxs32("div", { className: cn("flex min-h-screen flex-col bg-bg-surface", className), children: [
3189
- /* @__PURE__ */ jsxs32("header", { className: "flex shrink-0 items-center justify-between border-b border-border-subtle bg-bg-surface px-4 py-3", children: [
3190
- /* @__PURE__ */ jsxs32(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: [
3191
- /* @__PURE__ */ jsx62(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx62(Button, { variant: "ghost", size: "icon", className: "size-8 text-text-secondary", "aria-label": "Open navigation", children: /* @__PURE__ */ jsx62(Menu2, { className: "size-5" }) }) }),
3192
- /* @__PURE__ */ jsxs32(SheetContent, { side: "left", className: "w-[248px] bg-bg-surface p-0", children: [
3193
- /* @__PURE__ */ jsx62(SheetTitle, { className: "sr-only", children: "Navigation" }),
3194
- /* @__PURE__ */ jsx62(SheetDescription, { className: "sr-only", children: "Application navigation menu" }),
3445
+ return /* @__PURE__ */ jsx64(TooltipProvider, { children: /* @__PURE__ */ jsxs34("div", { className: cn("flex min-h-screen flex-col bg-bg-surface", className), children: [
3446
+ /* @__PURE__ */ jsxs34("header", { className: "flex shrink-0 items-center justify-between border-b border-border-subtle bg-bg-surface px-4 py-3", children: [
3447
+ /* @__PURE__ */ jsxs34(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: [
3448
+ /* @__PURE__ */ jsx64(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx64(Button, { variant: "ghost", size: "icon", className: "size-8 text-text-secondary", "aria-label": "Open navigation", children: /* @__PURE__ */ jsx64(Menu2, { className: "size-5" }) }) }),
3449
+ /* @__PURE__ */ jsxs34(SheetContent, { side: "left", className: "w-[248px] bg-bg-surface p-0", children: [
3450
+ /* @__PURE__ */ jsx64(SheetTitle, { className: "sr-only", children: "Navigation" }),
3451
+ /* @__PURE__ */ jsx64(SheetDescription, { className: "sr-only", children: "Application navigation menu" }),
3195
3452
  expandedSidebar(sidebar)
3196
3453
  ] })
3197
3454
  ] }),
3198
- /* @__PURE__ */ jsx62("div", { className: "flex items-center gap-2", children: topBar })
3455
+ /* @__PURE__ */ jsx64("div", { className: "flex items-center gap-2", children: topBar })
3199
3456
  ] }),
3200
- /* @__PURE__ */ jsx62("main", { className: "flex-1 overflow-auto", children })
3457
+ /* @__PURE__ */ jsx64("main", { className: "flex-1 overflow-auto", children })
3201
3458
  ] }) });
3202
3459
  }
3203
- return /* @__PURE__ */ jsx62(TooltipProvider, { children: /* @__PURE__ */ jsxs32("div", { className: cn("flex min-h-screen gap-3 bg-bg-surface p-4", className), children: [
3204
- /* @__PURE__ */ jsx62("div", { className: "sticky top-4 h-[calc(100vh-32px)] shrink-0", children: sidebar }),
3205
- /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", children: [
3206
- topBar && /* @__PURE__ */ jsx62("div", { className: "flex shrink-0 items-center justify-end gap-2", children: topBar }),
3207
- /* @__PURE__ */ jsx62("main", { className: "flex-1 overflow-y-auto", children })
3460
+ return /* @__PURE__ */ jsx64(TooltipProvider, { children: /* @__PURE__ */ jsxs34("div", { className: cn("flex min-h-screen gap-3 bg-bg-surface p-4", className), children: [
3461
+ /* @__PURE__ */ jsx64("div", { className: "sticky top-4 h-[calc(100vh-32px)] shrink-0", children: sidebar }),
3462
+ /* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", children: [
3463
+ topBar && /* @__PURE__ */ jsx64("div", { className: "flex shrink-0 items-center justify-end gap-2", children: topBar }),
3464
+ /* @__PURE__ */ jsx64("main", { className: "flex-1 overflow-y-auto", children })
3208
3465
  ] })
3209
3466
  ] }) });
3210
3467
  }
3211
3468
  var AuthenticatedLayout = AppShell;
3212
3469
 
3213
3470
  // src/components/grid.tsx
3214
- import * as React52 from "react";
3471
+ import * as React53 from "react";
3215
3472
  import { Slot as Slot6 } from "@radix-ui/react-slot";
3216
- import { jsx as jsx63 } from "react/jsx-runtime";
3217
- var Grid = React52.forwardRef(
3473
+ import { jsx as jsx65 } from "react/jsx-runtime";
3474
+ var Grid = React53.forwardRef(
3218
3475
  ({ fluid = false, asChild = false, className, ...props }, ref) => {
3219
3476
  const Comp = asChild ? Slot6 : "div";
3220
- return /* @__PURE__ */ jsx63(
3477
+ return /* @__PURE__ */ jsx65(
3221
3478
  Comp,
3222
3479
  {
3223
3480
  ref,
@@ -3235,9 +3492,9 @@ var Grid = React52.forwardRef(
3235
3492
  Grid.displayName = "Grid";
3236
3493
 
3237
3494
  // src/components/col.tsx
3238
- import * as React53 from "react";
3495
+ import * as React54 from "react";
3239
3496
  import { Slot as Slot7 } from "@radix-ui/react-slot";
3240
- import { jsx as jsx64 } from "react/jsx-runtime";
3497
+ import { jsx as jsx66 } from "react/jsx-runtime";
3241
3498
  var TIER_MAX = { base: 4, md: 8, xl: 12 };
3242
3499
  var SPAN = {
3243
3500
  base: { 1: "col-span-1", 2: "col-span-2", 3: "col-span-3", 4: "col-span-4" },
@@ -3357,22 +3614,194 @@ function responsiveClasses(span, offset) {
3357
3614
  }
3358
3615
  return cn(...spanClasses, ...startClasses);
3359
3616
  }
3360
- var Col = React53.forwardRef(
3617
+ var Col = React54.forwardRef(
3361
3618
  ({ span, offset, asChild = false, className, ...props }, ref) => {
3362
3619
  const Comp = asChild ? Slot7 : "div";
3363
- return /* @__PURE__ */ jsx64(Comp, { ref, className: cn(responsiveClasses(span, offset), className), ...props });
3620
+ return /* @__PURE__ */ jsx66(Comp, { ref, className: cn(responsiveClasses(span, offset), className), ...props });
3364
3621
  }
3365
3622
  );
3366
3623
  Col.displayName = "Col";
3367
3624
 
3625
+ // src/components/code-block.tsx
3626
+ import * as React55 from "react";
3627
+ import { jsx as jsx67, jsxs as jsxs35 } from "react/jsx-runtime";
3628
+ var TOKEN_CLASS = {
3629
+ comment: "text-text-tertiary italic",
3630
+ string: "text-text-success",
3631
+ keyword: "text-text-link",
3632
+ other: "text-text-secondary"
3633
+ };
3634
+ var TS_KEYWORDS = [
3635
+ "import",
3636
+ "from",
3637
+ "export",
3638
+ "default",
3639
+ "const",
3640
+ "let",
3641
+ "var",
3642
+ "function",
3643
+ "return",
3644
+ "new",
3645
+ "type",
3646
+ "interface",
3647
+ "enum",
3648
+ "extends",
3649
+ "implements",
3650
+ "class",
3651
+ "async",
3652
+ "await",
3653
+ "if",
3654
+ "else",
3655
+ "for",
3656
+ "while",
3657
+ "switch",
3658
+ "case",
3659
+ "break",
3660
+ "continue",
3661
+ "true",
3662
+ "false",
3663
+ "null",
3664
+ "undefined",
3665
+ "void",
3666
+ "as",
3667
+ "satisfies",
3668
+ "typeof",
3669
+ "keyof",
3670
+ "in",
3671
+ "of"
3672
+ ];
3673
+ var LANGS = {
3674
+ ts: { lineComment: "//", blockComment: true, keywords: TS_KEYWORDS },
3675
+ tsx: { lineComment: "//", blockComment: true, keywords: TS_KEYWORDS },
3676
+ bash: {
3677
+ lineComment: "#",
3678
+ blockComment: false,
3679
+ keywords: [
3680
+ "pnpm",
3681
+ "npm",
3682
+ "npx",
3683
+ "yarn",
3684
+ "node",
3685
+ "cd",
3686
+ "export",
3687
+ "echo",
3688
+ "sudo",
3689
+ "git",
3690
+ "rm",
3691
+ "mkdir",
3692
+ "cp",
3693
+ "mv",
3694
+ "ls",
3695
+ "cat",
3696
+ "set",
3697
+ "source"
3698
+ ]
3699
+ },
3700
+ json: { blockComment: false, keywords: ["true", "false", "null"] },
3701
+ css: {
3702
+ blockComment: true,
3703
+ keywords: [
3704
+ "important",
3705
+ "inherit",
3706
+ "initial",
3707
+ "unset",
3708
+ "none",
3709
+ "auto",
3710
+ "@media",
3711
+ "@import",
3712
+ "@keyframes",
3713
+ "@font-face",
3714
+ "@supports"
3715
+ ]
3716
+ }
3717
+ };
3718
+ function escapeRe(s) {
3719
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3720
+ }
3721
+ function buildRegex(cfg) {
3722
+ const commentAlts = [];
3723
+ if (cfg.blockComment) commentAlts.push("/\\*[\\s\\S]*?\\*/");
3724
+ if (cfg.lineComment) commentAlts.push(escapeRe(cfg.lineComment) + "[^\\n]*");
3725
+ const comment = commentAlts.length ? `(?<comment>${commentAlts.join("|")})` : "";
3726
+ const string = `(?<string>'(?:[^'\\\\]|\\\\.)*'|"(?:[^"\\\\]|\\\\.)*"|\`(?:[^\`\\\\]|\\\\.)*\`)`;
3727
+ const kw = cfg.keywords.map(escapeRe).join("|");
3728
+ const keyword = kw ? `(?<keyword>(?<![\\w$])(?:${kw})(?![\\w$]))` : "";
3729
+ const other = "(?<other>[\\s\\S])";
3730
+ const src = [comment, string, keyword, other].filter(Boolean).join("|");
3731
+ return new RegExp(src, "g");
3732
+ }
3733
+ var LANG_RE = {
3734
+ ts: buildRegex(LANGS.ts),
3735
+ tsx: buildRegex(LANGS.tsx),
3736
+ bash: buildRegex(LANGS.bash),
3737
+ json: buildRegex(LANGS.json),
3738
+ css: buildRegex(LANGS.css)
3739
+ };
3740
+ function tokenize(code, lang) {
3741
+ const tokens = [];
3742
+ for (const match of code.matchAll(LANG_RE[lang])) {
3743
+ const g = match.groups ?? {};
3744
+ const kind = g.comment != null ? "comment" : g.string != null ? "string" : g.keyword != null ? "keyword" : "other";
3745
+ const text = match[0];
3746
+ const prev = tokens[tokens.length - 1];
3747
+ if (prev && prev.kind === kind && kind === "other") {
3748
+ prev.text += text;
3749
+ } else {
3750
+ tokens.push({ kind, text });
3751
+ }
3752
+ }
3753
+ return tokens;
3754
+ }
3755
+ var CodeBlock = React55.forwardRef(
3756
+ ({ code, lang = "tsx", copy = false, filename, scroll = false, className, ...props }, ref) => {
3757
+ const tokens = React55.useMemo(() => tokenize(code, lang), [code, lang]);
3758
+ const framed = Boolean(filename) || copy;
3759
+ const pre = /* @__PURE__ */ jsx67(
3760
+ "pre",
3761
+ {
3762
+ ref,
3763
+ className: cn(
3764
+ "p-4 font-mono text-xs leading-6 text-text-secondary",
3765
+ scroll ? "overflow-x-auto" : "whitespace-pre-wrap break-words",
3766
+ !framed && "rounded-lg border border-border-subtle bg-bg-primary",
3767
+ className
3768
+ ),
3769
+ ...props,
3770
+ children: /* @__PURE__ */ jsx67("code", { children: tokens.map((token, index) => /* @__PURE__ */ jsx67("span", { className: TOKEN_CLASS[token.kind], children: token.text }, index)) })
3771
+ }
3772
+ );
3773
+ if (!framed) return pre;
3774
+ return /* @__PURE__ */ jsxs35("div", { className: "overflow-hidden rounded-lg border border-border-subtle bg-bg-primary", children: [
3775
+ /* @__PURE__ */ jsxs35("div", { className: "flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-2", children: [
3776
+ filename ? /* @__PURE__ */ jsx67("span", { className: "font-mono text-xs text-text-tertiary", children: filename }) : /* @__PURE__ */ jsx67("span", {}),
3777
+ copy ? /* @__PURE__ */ jsx67(CopyButton, { value: code, label: "Copy code" }) : null
3778
+ ] }),
3779
+ pre
3780
+ ] });
3781
+ }
3782
+ );
3783
+ CodeBlock.displayName = "CodeBlock";
3784
+ var Code = React55.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx67(
3785
+ "code",
3786
+ {
3787
+ ref,
3788
+ className: cn(
3789
+ "rounded border border-border-subtle bg-bg-secondary px-1.5 py-0.5 font-mono text-[0.85em] text-text-primary",
3790
+ className
3791
+ ),
3792
+ ...props
3793
+ }
3794
+ ));
3795
+ Code.displayName = "Code";
3796
+
3368
3797
  // src/components/grid-overlay.tsx
3369
- import * as React54 from "react";
3370
- import { jsx as jsx65 } from "react/jsx-runtime";
3798
+ import * as React56 from "react";
3799
+ import { jsx as jsx68 } from "react/jsx-runtime";
3371
3800
  var BASELINE = "var(--grid-gutter) / 2";
3372
- var GridOverlay = React54.forwardRef(
3801
+ var GridOverlay = React56.forwardRef(
3373
3802
  ({ columns, baseline = false, className, style, ...props }, ref) => {
3374
3803
  const count = Number.isFinite(columns) ? Math.max(1, Math.floor(columns)) : 1;
3375
- return /* @__PURE__ */ jsx65(
3804
+ return /* @__PURE__ */ jsx68(
3376
3805
  "div",
3377
3806
  {
3378
3807
  ref,
@@ -3389,7 +3818,7 @@ var GridOverlay = React54.forwardRef(
3389
3818
  ...style
3390
3819
  },
3391
3820
  ...props,
3392
- children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsx65("span", { style: { backgroundColor: "var(--bg-brand)", opacity: 0.1 } }, i))
3821
+ children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsx68("span", { style: { backgroundColor: "var(--bg-brand)", opacity: 0.1 } }, i))
3393
3822
  }
3394
3823
  );
3395
3824
  }
@@ -3397,10 +3826,10 @@ var GridOverlay = React54.forwardRef(
3397
3826
  GridOverlay.displayName = "GridOverlay";
3398
3827
 
3399
3828
  // src/components/segment-chip.tsx
3400
- import * as React55 from "react";
3829
+ import * as React57 from "react";
3401
3830
  import { cva as cva9 } from "class-variance-authority";
3402
3831
  import { Link2 as Link22, KeyRound, Clock, Plus } from "lucide-react";
3403
- import { jsx as jsx66, jsxs as jsxs33 } from "react/jsx-runtime";
3832
+ import { jsx as jsx69, jsxs as jsxs36 } from "react/jsx-runtime";
3404
3833
  var segmentChipVariants = cva9(
3405
3834
  "inline-flex items-center gap-1.5 rounded-lg border px-2.5 py-1 text-sm font-medium leading-tight",
3406
3835
  {
@@ -3421,11 +3850,11 @@ var kindIcons = {
3421
3850
  pending: Clock,
3422
3851
  available: Plus
3423
3852
  };
3424
- var SegmentChip = React55.forwardRef(
3853
+ var SegmentChip = React57.forwardRef(
3425
3854
  ({ kind, resource, icon, hideIcon = false, className, ...props }, ref) => {
3426
3855
  const Icon = icon ?? kindIcons[kind ?? "granted"];
3427
- return /* @__PURE__ */ jsxs33("span", { ref, className: cn(segmentChipVariants({ kind }), className), ...props, children: [
3428
- !hideIcon && /* @__PURE__ */ jsx66(Icon, { className: "size-3.5 shrink-0 opacity-90", "aria-hidden": "true" }),
3856
+ return /* @__PURE__ */ jsxs36("span", { ref, className: cn(segmentChipVariants({ kind }), className), ...props, children: [
3857
+ !hideIcon && /* @__PURE__ */ jsx69(Icon, { className: "size-3.5 shrink-0 opacity-90", "aria-hidden": "true" }),
3429
3858
  resource
3430
3859
  ] });
3431
3860
  }
@@ -3433,9 +3862,9 @@ var SegmentChip = React55.forwardRef(
3433
3862
  SegmentChip.displayName = "SegmentChip";
3434
3863
 
3435
3864
  // src/components/connection-card.tsx
3436
- import * as React56 from "react";
3865
+ import * as React58 from "react";
3437
3866
  import { AlertTriangle, ChevronDown as ChevronDown4 } from "lucide-react";
3438
- import { Fragment as Fragment5, jsx as jsx67, jsxs as jsxs34 } from "react/jsx-runtime";
3867
+ import { Fragment as Fragment7, jsx as jsx70, jsxs as jsxs37 } from "react/jsx-runtime";
3439
3868
  var authLabels = { app: "App", oauth: "OAuth", token: "token" };
3440
3869
  var statusMeta = {
3441
3870
  connected: { label: "Connected", badge: "success", dot: "success" },
@@ -3445,7 +3874,7 @@ var statusMeta = {
3445
3874
  function monogram(name) {
3446
3875
  return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
3447
3876
  }
3448
- var ConnectionCard = React56.forwardRef(
3877
+ var ConnectionCard = React58.forwardRef(
3449
3878
  ({
3450
3879
  name,
3451
3880
  scope,
@@ -3466,7 +3895,7 @@ var ConnectionCard = React56.forwardRef(
3466
3895
  }, ref) => {
3467
3896
  const meta = statusMeta[status];
3468
3897
  const connected = status !== "disconnected";
3469
- const glyphBox = /* @__PURE__ */ jsx67(
3898
+ const glyphBox = /* @__PURE__ */ jsx70(
3470
3899
  "div",
3471
3900
  {
3472
3901
  "aria-hidden": "true",
@@ -3474,51 +3903,51 @@ var ConnectionCard = React56.forwardRef(
3474
3903
  children: glyph ?? monogram(name)
3475
3904
  }
3476
3905
  );
3477
- const identity = /* @__PURE__ */ jsxs34("div", { className: "min-w-0", children: [
3478
- /* @__PURE__ */ jsx67("p", { className: "truncate text-sm font-semibold text-text-primary", children: name }),
3479
- /* @__PURE__ */ jsxs34("div", { className: "mt-0.5 flex flex-wrap gap-1", children: [
3480
- /* @__PURE__ */ jsx67(Badge, { variant: "secondary", children: scope }),
3481
- /* @__PURE__ */ jsx67(Badge, { variant: "secondary", children: authLabels[auth] })
3906
+ const identity = /* @__PURE__ */ jsxs37("div", { className: "min-w-0", children: [
3907
+ /* @__PURE__ */ jsx70("p", { className: "truncate text-sm font-semibold text-text-primary", children: name }),
3908
+ /* @__PURE__ */ jsxs37("div", { className: "mt-0.5 flex flex-wrap gap-1", children: [
3909
+ /* @__PURE__ */ jsx70(Badge, { variant: "secondary", children: scope }),
3910
+ /* @__PURE__ */ jsx70(Badge, { variant: "secondary", children: authLabels[auth] })
3482
3911
  ] })
3483
3912
  ] });
3484
- const statusBadge = /* @__PURE__ */ jsxs34(Badge, { variant: meta.badge, className: "gap-1.5", children: [
3485
- /* @__PURE__ */ jsx67(StatusDot, { status: meta.dot, size: "sm" }),
3913
+ const statusBadge = /* @__PURE__ */ jsxs37(Badge, { variant: meta.badge, className: "gap-1.5", children: [
3914
+ /* @__PURE__ */ jsx70(StatusDot, { status: meta.dot, size: "sm" }),
3486
3915
  statusLabel ?? meta.label
3487
3916
  ] });
3488
- const accessNote = access ? /* @__PURE__ */ jsxs34(
3917
+ const accessNote = access ? /* @__PURE__ */ jsxs37(
3489
3918
  "div",
3490
3919
  {
3491
3920
  role: "note",
3492
3921
  className: "flex items-start gap-2 border-t border-border-subtle bg-bg-warning-subtle px-4 py-2.5 text-xs font-medium text-text-warning",
3493
3922
  children: [
3494
- /* @__PURE__ */ jsx67(AlertTriangle, { className: "mt-0.5 size-3.5 shrink-0", "aria-hidden": "true" }),
3495
- /* @__PURE__ */ jsx67("span", { children: access })
3923
+ /* @__PURE__ */ jsx70(AlertTriangle, { className: "mt-0.5 size-3.5 shrink-0", "aria-hidden": "true" }),
3924
+ /* @__PURE__ */ jsx70("span", { children: access })
3496
3925
  ]
3497
3926
  }
3498
3927
  ) : null;
3499
3928
  const footerAction = collapsible ? action : connected && action;
3500
- const footer = grantedCount !== void 0 || footerAction ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between border-t border-border-subtle px-4 py-3", children: [
3501
- /* @__PURE__ */ jsx67("span", { className: "text-sm text-text-secondary", children: grantedCount !== void 0 ? /* @__PURE__ */ jsxs34(Fragment5, { children: [
3929
+ const footer = grantedCount !== void 0 || footerAction ? /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between border-t border-border-subtle px-4 py-3", children: [
3930
+ /* @__PURE__ */ jsx70("span", { className: "text-sm text-text-secondary", children: grantedCount !== void 0 ? /* @__PURE__ */ jsxs37(Fragment7, { children: [
3502
3931
  "Granted to ",
3503
- /* @__PURE__ */ jsx67("span", { className: "font-semibold text-text-primary", children: grantedCount }),
3932
+ /* @__PURE__ */ jsx70("span", { className: "font-semibold text-text-primary", children: grantedCount }),
3504
3933
  " ",
3505
3934
  grantedCount === 1 ? "product" : "products"
3506
- ] }) : /* @__PURE__ */ jsx67("span", { className: "text-text-tertiary", children: "Not granted to any product yet" }) }),
3935
+ ] }) : /* @__PURE__ */ jsx70("span", { className: "text-text-tertiary", children: "Not granted to any product yet" }) }),
3507
3936
  footerAction
3508
3937
  ] }) : null;
3509
- const drawer = children ? /* @__PURE__ */ jsx67("div", { "data-slot": "drawer", className: "border-t border-border-subtle", children }) : null;
3938
+ const drawer = children ? /* @__PURE__ */ jsx70("div", { "data-slot": "drawer", className: "border-t border-border-subtle", children }) : null;
3510
3939
  if (!collapsible) {
3511
- return /* @__PURE__ */ jsxs34(
3940
+ return /* @__PURE__ */ jsxs37(
3512
3941
  Card,
3513
3942
  {
3514
3943
  ref,
3515
3944
  className: cn(status === "disconnected" && "border-dashed border-border-default", className),
3516
3945
  ...props,
3517
3946
  children: [
3518
- /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-3 p-4", children: [
3947
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-3 p-4", children: [
3519
3948
  glyphBox,
3520
3949
  identity,
3521
- /* @__PURE__ */ jsx67("div", { className: "ml-auto shrink-0", children: connected ? statusBadge : action })
3950
+ /* @__PURE__ */ jsx70("div", { className: "ml-auto shrink-0", children: connected ? statusBadge : action })
3522
3951
  ] }),
3523
3952
  accessNote,
3524
3953
  footer,
@@ -3527,7 +3956,7 @@ var ConnectionCard = React56.forwardRef(
3527
3956
  }
3528
3957
  );
3529
3958
  }
3530
- return /* @__PURE__ */ jsx67(Collapsible, { defaultOpen, open, onOpenChange, children: /* @__PURE__ */ jsxs34(
3959
+ return /* @__PURE__ */ jsx70(Collapsible, { defaultOpen, open, onOpenChange, children: /* @__PURE__ */ jsxs37(
3531
3960
  Card,
3532
3961
  {
3533
3962
  ref,
@@ -3538,7 +3967,7 @@ var ConnectionCard = React56.forwardRef(
3538
3967
  ),
3539
3968
  ...props,
3540
3969
  children: [
3541
- /* @__PURE__ */ jsx67(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs34(
3970
+ /* @__PURE__ */ jsx70(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs37(
3542
3971
  "button",
3543
3972
  {
3544
3973
  type: "button",
@@ -3546,9 +3975,9 @@ var ConnectionCard = React56.forwardRef(
3546
3975
  children: [
3547
3976
  glyphBox,
3548
3977
  identity,
3549
- /* @__PURE__ */ jsxs34("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
3978
+ /* @__PURE__ */ jsxs37("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
3550
3979
  statusBadge,
3551
- /* @__PURE__ */ jsx67(
3980
+ /* @__PURE__ */ jsx70(
3552
3981
  ChevronDown4,
3553
3982
  {
3554
3983
  "aria-hidden": "true",
@@ -3559,7 +3988,7 @@ var ConnectionCard = React56.forwardRef(
3559
3988
  ]
3560
3989
  }
3561
3990
  ) }),
3562
- /* @__PURE__ */ jsxs34(CollapsibleContent2, { children: [
3991
+ /* @__PURE__ */ jsxs37(CollapsibleContent2, { children: [
3563
3992
  accessNote,
3564
3993
  footer,
3565
3994
  drawer
@@ -3572,32 +4001,32 @@ var ConnectionCard = React56.forwardRef(
3572
4001
  ConnectionCard.displayName = "ConnectionCard";
3573
4002
 
3574
4003
  // src/components/request-row.tsx
3575
- import * as React57 from "react";
3576
- import { Fragment as Fragment6, jsx as jsx68, jsxs as jsxs35 } from "react/jsx-runtime";
4004
+ import * as React59 from "react";
4005
+ import { Fragment as Fragment8, jsx as jsx71, jsxs as jsxs38 } from "react/jsx-runtime";
3577
4006
  function monogram2(name) {
3578
4007
  return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
3579
4008
  }
3580
- var RequestRow = React57.forwardRef(
4009
+ var RequestRow = React59.forwardRef(
3581
4010
  ({ surface, name, state: state2, glyph, subtitle, grantedResource, onApprove, onDeny, onRequest, action, className, ...props }, ref) => {
3582
4011
  let controls = action;
3583
4012
  if (controls === void 0) {
3584
4013
  if (surface === "org" && state2 === "pending") {
3585
- controls = /* @__PURE__ */ jsxs35(Fragment6, { children: [
3586
- /* @__PURE__ */ jsx68(Button, { variant: "outline", size: "sm", onClick: onDeny, children: "Deny" }),
3587
- /* @__PURE__ */ jsx68(Button, { size: "sm", onClick: onApprove, children: "Approve" })
4014
+ controls = /* @__PURE__ */ jsxs38(Fragment8, { children: [
4015
+ /* @__PURE__ */ jsx71(Button, { variant: "outline", size: "sm", onClick: onDeny, children: "Deny" }),
4016
+ /* @__PURE__ */ jsx71(Button, { size: "sm", onClick: onApprove, children: "Approve" })
3588
4017
  ] });
3589
4018
  } else if (state2 === "available") {
3590
- controls = /* @__PURE__ */ jsx68(Button, { size: "sm", onClick: onRequest, children: "Request" });
4019
+ controls = /* @__PURE__ */ jsx71(Button, { size: "sm", onClick: onRequest, children: "Request" });
3591
4020
  } else if (state2 === "pending") {
3592
- controls = /* @__PURE__ */ jsxs35(Badge, { variant: "secondary", className: "gap-1.5", children: [
3593
- /* @__PURE__ */ jsx68(StatusDot, { status: "neutral", size: "sm" }),
4021
+ controls = /* @__PURE__ */ jsxs38(Badge, { variant: "secondary", className: "gap-1.5", children: [
4022
+ /* @__PURE__ */ jsx71(StatusDot, { status: "neutral", size: "sm" }),
3594
4023
  "Pending"
3595
4024
  ] });
3596
4025
  } else if (state2 === "granted") {
3597
- controls = /* @__PURE__ */ jsx68(SegmentChip, { kind: "granted", resource: grantedResource ?? "a segment" });
4026
+ controls = /* @__PURE__ */ jsx71(SegmentChip, { kind: "granted", resource: grantedResource ?? "a segment" });
3598
4027
  }
3599
4028
  }
3600
- return /* @__PURE__ */ jsxs35(
4029
+ return /* @__PURE__ */ jsxs38(
3601
4030
  "div",
3602
4031
  {
3603
4032
  ref,
@@ -3607,7 +4036,7 @@ var RequestRow = React57.forwardRef(
3607
4036
  ),
3608
4037
  ...props,
3609
4038
  children: [
3610
- /* @__PURE__ */ jsx68(
4039
+ /* @__PURE__ */ jsx71(
3611
4040
  "div",
3612
4041
  {
3613
4042
  "aria-hidden": "true",
@@ -3615,11 +4044,11 @@ var RequestRow = React57.forwardRef(
3615
4044
  children: glyph ?? monogram2(name)
3616
4045
  }
3617
4046
  ),
3618
- /* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
3619
- /* @__PURE__ */ jsx68("p", { className: "truncate text-sm font-semibold text-text-primary", children: name }),
3620
- subtitle && /* @__PURE__ */ jsx68("p", { className: "truncate text-xs text-text-tertiary", children: subtitle })
4047
+ /* @__PURE__ */ jsxs38("div", { className: "min-w-0", children: [
4048
+ /* @__PURE__ */ jsx71("p", { className: "truncate text-sm font-semibold text-text-primary", children: name }),
4049
+ subtitle && /* @__PURE__ */ jsx71("p", { className: "truncate text-xs text-text-tertiary", children: subtitle })
3621
4050
  ] }),
3622
- /* @__PURE__ */ jsx68("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: controls })
4051
+ /* @__PURE__ */ jsx71("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: controls })
3623
4052
  ]
3624
4053
  }
3625
4054
  );
@@ -3628,9 +4057,9 @@ var RequestRow = React57.forwardRef(
3628
4057
  RequestRow.displayName = "RequestRow";
3629
4058
 
3630
4059
  // src/components/feedback-button.tsx
3631
- import * as React58 from "react";
4060
+ import * as React60 from "react";
3632
4061
  import { MessageSquare, Loader2 as Loader22, CheckCircle2 } from "lucide-react";
3633
- import { jsx as jsx69, jsxs as jsxs36 } from "react/jsx-runtime";
4062
+ import { jsx as jsx72, jsxs as jsxs39 } from "react/jsx-runtime";
3634
4063
  var TITLE_MAX = 256;
3635
4064
  var DETAILS_MAX = 65536;
3636
4065
  var DEFAULT_LABELS = {
@@ -3644,15 +4073,15 @@ var DEFAULT_LABELS = {
3644
4073
  };
3645
4074
  function FeedbackButton({ onSubmit, labels, className }) {
3646
4075
  const l = { ...DEFAULT_LABELS, ...labels };
3647
- const uid = React58.useId();
4076
+ const uid = React60.useId();
3648
4077
  const titleId = `${uid}-title`;
3649
4078
  const detailsId = `${uid}-details`;
3650
4079
  const titleErrId = `${uid}-title-error`;
3651
4080
  const detailsErrId = `${uid}-details-error`;
3652
- const [open, setOpen] = React58.useState(false);
3653
- const [status, setStatus] = React58.useState("idle");
3654
- const [title, setTitle] = React58.useState("");
3655
- const [details, setDetails] = React58.useState("");
4081
+ const [open, setOpen] = React60.useState(false);
4082
+ const [status, setStatus] = React60.useState("idle");
4083
+ const [title, setTitle] = React60.useState("");
4084
+ const [details, setDetails] = React60.useState("");
3656
4085
  const titleTooLong = title.length > TITLE_MAX;
3657
4086
  const detailsTooLong = details.length > DETAILS_MAX;
3658
4087
  const titleEmpty = title.trim().length === 0;
@@ -3677,20 +4106,20 @@ function FeedbackButton({ onSubmit, labels, className }) {
3677
4106
  setStatus("error");
3678
4107
  }
3679
4108
  };
3680
- return /* @__PURE__ */ jsxs36(Popover, { open, onOpenChange: changeOpen, children: [
3681
- /* @__PURE__ */ jsx69(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs36(Button, { variant: "ghost", size: "sm", "aria-label": l.trigger, className, children: [
3682
- /* @__PURE__ */ jsx69(MessageSquare, { className: "size-4", "aria-hidden": "true" }),
4109
+ return /* @__PURE__ */ jsxs39(Popover, { open, onOpenChange: changeOpen, children: [
4110
+ /* @__PURE__ */ jsx72(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs39(Button, { variant: "ghost", size: "sm", "aria-label": l.trigger, className, children: [
4111
+ /* @__PURE__ */ jsx72(MessageSquare, { className: "size-4", "aria-hidden": "true" }),
3683
4112
  l.trigger
3684
4113
  ] }) }),
3685
- /* @__PURE__ */ jsx69(PopoverContent, { align: "end", side: "bottom", className: "w-80", children: status === "success" ? /* @__PURE__ */ jsxs36("div", { className: "flex flex-col items-center gap-3 py-2 text-center", children: [
3686
- /* @__PURE__ */ jsx69(CheckCircle2, { className: "size-8 text-text-success", "aria-hidden": "true" }),
3687
- /* @__PURE__ */ jsx69("p", { role: "status", className: "text-sm text-text-primary", children: l.success }),
3688
- /* @__PURE__ */ jsx69(Button, { variant: "outline", size: "sm", onClick: () => changeOpen(false), children: "Close" })
3689
- ] }) : /* @__PURE__ */ jsxs36("form", { onSubmit: handleSubmit, className: "flex flex-col gap-3", children: [
3690
- /* @__PURE__ */ jsx69("p", { className: "text-sm font-medium text-text-primary", children: l.title }),
3691
- /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-1.5", children: [
3692
- /* @__PURE__ */ jsx69(Label2, { htmlFor: titleId, children: l.titleField }),
3693
- /* @__PURE__ */ jsx69(
4114
+ /* @__PURE__ */ jsx72(PopoverContent, { align: "end", side: "bottom", className: "w-80", children: status === "success" ? /* @__PURE__ */ jsxs39("div", { className: "flex flex-col items-center gap-3 py-2 text-center", children: [
4115
+ /* @__PURE__ */ jsx72(CheckCircle2, { className: "size-8 text-text-success", "aria-hidden": "true" }),
4116
+ /* @__PURE__ */ jsx72("p", { role: "status", className: "text-sm text-text-primary", children: l.success }),
4117
+ /* @__PURE__ */ jsx72(Button, { variant: "outline", size: "sm", onClick: () => changeOpen(false), children: "Close" })
4118
+ ] }) : /* @__PURE__ */ jsxs39("form", { onSubmit: handleSubmit, className: "flex flex-col gap-3", children: [
4119
+ /* @__PURE__ */ jsx72("p", { className: "text-sm font-medium text-text-primary", children: l.title }),
4120
+ /* @__PURE__ */ jsxs39("div", { className: "flex flex-col gap-1.5", children: [
4121
+ /* @__PURE__ */ jsx72(Label2, { htmlFor: titleId, children: l.titleField }),
4122
+ /* @__PURE__ */ jsx72(
3694
4123
  Input,
3695
4124
  {
3696
4125
  id: titleId,
@@ -3701,16 +4130,16 @@ function FeedbackButton({ onSubmit, labels, className }) {
3701
4130
  "aria-describedby": titleTooLong ? titleErrId : void 0
3702
4131
  }
3703
4132
  ),
3704
- titleTooLong && /* @__PURE__ */ jsxs36("p", { id: titleErrId, className: "text-xs text-text-danger", children: [
4133
+ titleTooLong && /* @__PURE__ */ jsxs39("p", { id: titleErrId, className: "text-xs text-text-danger", children: [
3705
4134
  l.titleField,
3706
4135
  " must be ",
3707
4136
  TITLE_MAX,
3708
4137
  " characters or fewer."
3709
4138
  ] })
3710
4139
  ] }),
3711
- /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-1.5", children: [
3712
- /* @__PURE__ */ jsx69(Label2, { htmlFor: detailsId, children: l.detailsField }),
3713
- /* @__PURE__ */ jsx69(
4140
+ /* @__PURE__ */ jsxs39("div", { className: "flex flex-col gap-1.5", children: [
4141
+ /* @__PURE__ */ jsx72(Label2, { htmlFor: detailsId, children: l.detailsField }),
4142
+ /* @__PURE__ */ jsx72(
3714
4143
  Textarea,
3715
4144
  {
3716
4145
  id: detailsId,
@@ -3721,16 +4150,16 @@ function FeedbackButton({ onSubmit, labels, className }) {
3721
4150
  "aria-describedby": detailsTooLong ? detailsErrId : void 0
3722
4151
  }
3723
4152
  ),
3724
- detailsTooLong && /* @__PURE__ */ jsxs36("p", { id: detailsErrId, className: "text-xs text-text-danger", children: [
4153
+ detailsTooLong && /* @__PURE__ */ jsxs39("p", { id: detailsErrId, className: "text-xs text-text-danger", children: [
3725
4154
  l.detailsField,
3726
4155
  " must be ",
3727
4156
  DETAILS_MAX,
3728
4157
  " characters or fewer."
3729
4158
  ] })
3730
4159
  ] }),
3731
- status === "error" && /* @__PURE__ */ jsx69(InlineError, { children: l.error }),
3732
- /* @__PURE__ */ jsxs36(Button, { type: "submit", disabled: !valid || submitting, children: [
3733
- submitting && /* @__PURE__ */ jsx69(Loader22, { className: "size-4 animate-spin", "aria-hidden": "true" }),
4160
+ status === "error" && /* @__PURE__ */ jsx72(InlineError, { children: l.error }),
4161
+ /* @__PURE__ */ jsxs39(Button, { type: "submit", disabled: !valid || submitting, children: [
4162
+ submitting && /* @__PURE__ */ jsx72(Loader22, { className: "size-4 animate-spin", "aria-hidden": "true" }),
3734
4163
  l.submit
3735
4164
  ] })
3736
4165
  ] }) })
@@ -3739,7 +4168,7 @@ function FeedbackButton({ onSubmit, labels, className }) {
3739
4168
 
3740
4169
  // src/components/create-product-window.tsx
3741
4170
  import { useForm } from "react-hook-form";
3742
- import { jsx as jsx70, jsxs as jsxs37 } from "react/jsx-runtime";
4171
+ import { jsx as jsx73, jsxs as jsxs40 } from "react/jsx-runtime";
3743
4172
  var CREATE_ORG_VALUE = "__create_new_org__";
3744
4173
  function CreateProductWindow({
3745
4174
  organizations,
@@ -3772,10 +4201,10 @@ function CreateProductWindow({
3772
4201
  }
3773
4202
  });
3774
4203
  const showSelect = organizations.length > 0;
3775
- return /* @__PURE__ */ jsxs37("div", { className: "flex w-full max-w-md flex-col gap-6", children: [
3776
- showSelect && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
3777
- /* @__PURE__ */ jsx70("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Organization" }),
3778
- /* @__PURE__ */ jsx70(
4204
+ return /* @__PURE__ */ jsxs40("div", { className: "flex w-full max-w-md flex-col gap-6", children: [
4205
+ showSelect && /* @__PURE__ */ jsxs40("div", { className: "space-y-2", children: [
4206
+ /* @__PURE__ */ jsx73("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Organization" }),
4207
+ /* @__PURE__ */ jsx73(
3779
4208
  Select,
3780
4209
  {
3781
4210
  "data-testid": "create-product-org-select",
@@ -3788,9 +4217,9 @@ function CreateProductWindow({
3788
4217
  }
3789
4218
  )
3790
4219
  ] }),
3791
- !createOrgMode && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
3792
- /* @__PURE__ */ jsx70("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Products" }),
3793
- productsLoading ? /* @__PURE__ */ jsx70("p", { className: "text-sm text-text-tertiary", children: "Loading products\u2026" }) : products.length === 0 ? /* @__PURE__ */ jsx70("p", { className: "text-sm text-text-tertiary", children: "No products yet." }) : /* @__PURE__ */ jsx70("ul", { className: "flex flex-col gap-1", children: products.map((product) => /* @__PURE__ */ jsx70("li", { children: /* @__PURE__ */ jsxs37(
4220
+ !createOrgMode && /* @__PURE__ */ jsxs40("div", { className: "space-y-2", children: [
4221
+ /* @__PURE__ */ jsx73("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Products" }),
4222
+ productsLoading ? /* @__PURE__ */ jsx73("p", { className: "text-sm text-text-tertiary", children: "Loading products\u2026" }) : products.length === 0 ? /* @__PURE__ */ jsx73("p", { className: "text-sm text-text-tertiary", children: "No products yet." }) : /* @__PURE__ */ jsx73("ul", { className: "flex flex-col gap-1", children: products.map((product) => /* @__PURE__ */ jsx73("li", { children: /* @__PURE__ */ jsxs40(
3794
4223
  "button",
3795
4224
  {
3796
4225
  type: "button",
@@ -3799,14 +4228,14 @@ function CreateProductWindow({
3799
4228
  "flex w-full items-center justify-between rounded-md border border-border-default bg-bg-primary px-3 py-2 text-left text-sm text-text-primary hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
3800
4229
  ),
3801
4230
  children: [
3802
- /* @__PURE__ */ jsx70("span", { className: "truncate", children: product.name }),
3803
- /* @__PURE__ */ jsx70("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
4231
+ /* @__PURE__ */ jsx73("span", { className: "truncate", children: product.name }),
4232
+ /* @__PURE__ */ jsx73("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
3804
4233
  ]
3805
4234
  }
3806
4235
  ) }, product.id)) })
3807
4236
  ] }),
3808
- /* @__PURE__ */ jsx70(Form, { ...form, children: /* @__PURE__ */ jsxs37("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4", noValidate: true, children: [
3809
- createOrgMode && /* @__PURE__ */ jsx70(
4237
+ /* @__PURE__ */ jsx73(Form, { ...form, children: /* @__PURE__ */ jsxs40("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4", noValidate: true, children: [
4238
+ createOrgMode && /* @__PURE__ */ jsx73(
3810
4239
  FormField,
3811
4240
  {
3812
4241
  control: form.control,
@@ -3814,14 +4243,14 @@ function CreateProductWindow({
3814
4243
  rules: {
3815
4244
  validate: (value) => value.trim().length > 0 || "Organization name is required"
3816
4245
  },
3817
- render: ({ field }) => /* @__PURE__ */ jsxs37(FormItem, { children: [
3818
- /* @__PURE__ */ jsx70(FormLabel, { children: "Organization name" }),
3819
- /* @__PURE__ */ jsx70(FormControl, { children: /* @__PURE__ */ jsx70(Input, { placeholder: "Acme Inc.", ...field }) }),
3820
- /* @__PURE__ */ jsx70(FormMessage, {})
4246
+ render: ({ field }) => /* @__PURE__ */ jsxs40(FormItem, { children: [
4247
+ /* @__PURE__ */ jsx73(FormLabel, { children: "Organization name" }),
4248
+ /* @__PURE__ */ jsx73(FormControl, { children: /* @__PURE__ */ jsx73(Input, { placeholder: "Acme Inc.", ...field }) }),
4249
+ /* @__PURE__ */ jsx73(FormMessage, {})
3821
4250
  ] })
3822
4251
  }
3823
4252
  ),
3824
- /* @__PURE__ */ jsx70(
4253
+ /* @__PURE__ */ jsx73(
3825
4254
  FormField,
3826
4255
  {
3827
4256
  control: form.control,
@@ -3829,18 +4258,619 @@ function CreateProductWindow({
3829
4258
  rules: {
3830
4259
  validate: (value) => value.trim().length > 0 || "Product name is required"
3831
4260
  },
3832
- render: ({ field }) => /* @__PURE__ */ jsxs37(FormItem, { children: [
3833
- /* @__PURE__ */ jsx70(FormLabel, { children: "Product name" }),
3834
- /* @__PURE__ */ jsx70(FormControl, { children: /* @__PURE__ */ jsx70(Input, { placeholder: "My product", ...field }) }),
3835
- /* @__PURE__ */ jsx70(FormMessage, {})
4261
+ render: ({ field }) => /* @__PURE__ */ jsxs40(FormItem, { children: [
4262
+ /* @__PURE__ */ jsx73(FormLabel, { children: "Product name" }),
4263
+ /* @__PURE__ */ jsx73(FormControl, { children: /* @__PURE__ */ jsx73(Input, { placeholder: "My product", ...field }) }),
4264
+ /* @__PURE__ */ jsx73(FormMessage, {})
3836
4265
  ] })
3837
4266
  }
3838
4267
  ),
3839
- error && /* @__PURE__ */ jsx70(InlineError, { children: error }),
3840
- /* @__PURE__ */ jsx70(Button, { type: "submit", disabled: submitting, children: "Create product" })
4268
+ error && /* @__PURE__ */ jsx73(InlineError, { children: error }),
4269
+ /* @__PURE__ */ jsx73(Button, { type: "submit", disabled: submitting, children: "Create product" })
3841
4270
  ] }) })
3842
4271
  ] });
3843
4272
  }
4273
+
4274
+ // src/components/notification-types.ts
4275
+ var severityLabels = {
4276
+ critical: "Critical",
4277
+ important: "Important",
4278
+ fyi: "FYI"
4279
+ };
4280
+ var severityBadgeVariants = {
4281
+ critical: "destructive",
4282
+ important: "warning",
4283
+ fyi: "secondary"
4284
+ };
4285
+ function severityBadgeVariant(severity) {
4286
+ return severityBadgeVariants[severity];
4287
+ }
4288
+ function formatRelativeAge(createdAt, now = /* @__PURE__ */ new Date()) {
4289
+ const then = createdAt instanceof Date ? createdAt : new Date(createdAt);
4290
+ const seconds = Math.max(0, Math.floor((now.getTime() - then.getTime()) / 1e3));
4291
+ if (seconds < 5) return "now";
4292
+ if (seconds < 60) return `${seconds}s ago`;
4293
+ const minutes = Math.floor(seconds / 60);
4294
+ if (minutes < 60) return `${minutes}m ago`;
4295
+ return `${Math.floor(minutes / 60)}h ago`;
4296
+ }
4297
+ function isNotificationSettled(item) {
4298
+ if (item.cls === "ephemeral") return false;
4299
+ return Boolean(item.receipt) || item.read === true;
4300
+ }
4301
+
4302
+ // src/components/notification-bell.tsx
4303
+ import * as React61 from "react";
4304
+ import { BellRing, Settings } from "lucide-react";
4305
+ import { jsx as jsx74, jsxs as jsxs41 } from "react/jsx-runtime";
4306
+ function BellRow({
4307
+ item,
4308
+ onItemClick,
4309
+ onActionClick,
4310
+ formatAge
4311
+ }) {
4312
+ const settled = isNotificationSettled(item);
4313
+ const unread = !settled && !item.read;
4314
+ const actions = settled ? [] : item.actions ?? [];
4315
+ const age = item.createdAt ? formatAge(item.createdAt instanceof Date ? item.createdAt : new Date(item.createdAt)) : null;
4316
+ return /* @__PURE__ */ jsxs41("div", { className: cn("rounded-lg bg-bg-surface px-3 py-2.5", settled && "opacity-45"), children: [
4317
+ /* @__PURE__ */ jsxs41("div", { className: "flex items-start gap-2.5", children: [
4318
+ /* @__PURE__ */ jsxs41("div", { className: "min-w-0 flex-1", children: [
4319
+ /* @__PURE__ */ jsx74(
4320
+ "button",
4321
+ {
4322
+ type: "button",
4323
+ onClick: () => onItemClick?.(item),
4324
+ className: cn(
4325
+ "block text-left text-sm leading-tight underline-offset-2 hover:underline",
4326
+ unread ? "font-semibold text-text-primary" : "text-text-secondary"
4327
+ ),
4328
+ children: item.title
4329
+ }
4330
+ ),
4331
+ /* @__PURE__ */ jsxs41("p", { className: "mt-1 truncate text-xs text-text-tertiary", children: [
4332
+ /* @__PURE__ */ jsx74("span", { className: "font-semibold uppercase tracking-wide text-text-secondary", children: item.source }),
4333
+ item.receipt ? `, ${item.receipt}` : ""
4334
+ ] })
4335
+ ] }),
4336
+ age && /* @__PURE__ */ jsx74("span", { className: "mt-px shrink-0 text-xs text-text-tertiary", children: age })
4337
+ ] }),
4338
+ (actions.length > 0 || item.deepLink) && /* @__PURE__ */ jsxs41("div", { className: "mt-2 flex flex-wrap items-center gap-x-4 gap-y-2", children: [
4339
+ actions.map((action) => {
4340
+ const chip = action.variant === "primary" || action.variant === "destructive";
4341
+ return /* @__PURE__ */ jsx74(
4342
+ "button",
4343
+ {
4344
+ type: "button",
4345
+ onClick: () => onActionClick?.(item, action),
4346
+ className: cn(
4347
+ chip ? "rounded-md px-2.5 py-1 text-xs font-medium transition-colors" : "text-xs font-semibold text-text-secondary transition-opacity hover:opacity-80",
4348
+ action.variant === "primary" && "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover",
4349
+ action.variant === "destructive" && "bg-bg-elevated text-text-danger hover:bg-bg-sunken"
4350
+ ),
4351
+ children: action.label
4352
+ },
4353
+ action.id
4354
+ );
4355
+ }),
4356
+ item.deepLink && /* @__PURE__ */ jsx74(
4357
+ "button",
4358
+ {
4359
+ type: "button",
4360
+ onClick: () => onItemClick?.(item),
4361
+ className: "text-xs font-semibold text-text-brand transition-opacity hover:opacity-80",
4362
+ children: item.deepLink.label
4363
+ }
4364
+ )
4365
+ ] })
4366
+ ] });
4367
+ }
4368
+ var NotificationBell = React61.forwardRef(
4369
+ ({
4370
+ items,
4371
+ unreadCount,
4372
+ maxItems = 5,
4373
+ onMarkAllRead,
4374
+ onItemClick,
4375
+ onActionClick,
4376
+ onOpenSettings,
4377
+ onOpenArchive,
4378
+ open,
4379
+ onOpenChange,
4380
+ formatAge,
4381
+ className
4382
+ }, ref) => {
4383
+ const unread = unreadCount ?? items.filter((n) => !n.read && n.cls !== "ephemeral").length;
4384
+ const age = React61.useCallback(
4385
+ (createdAt) => formatAge ? formatAge(createdAt) : formatRelativeAge(createdAt),
4386
+ [formatAge]
4387
+ );
4388
+ const rows = items.slice(0, maxItems);
4389
+ return /* @__PURE__ */ jsxs41(Popover, { open, onOpenChange, children: [
4390
+ /* @__PURE__ */ jsx74(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs41(
4391
+ "button",
4392
+ {
4393
+ ref,
4394
+ type: "button",
4395
+ "aria-label": "Notifications",
4396
+ className: cn(
4397
+ "relative flex size-8 items-center justify-center rounded-lg text-text-secondary transition-colors hover:bg-bg-elevated hover:text-text-primary data-[state=open]:bg-bg-brand-subtle data-[state=open]:text-text-brand",
4398
+ className
4399
+ ),
4400
+ children: [
4401
+ /* @__PURE__ */ jsx74(BellRing, { className: "size-[18px]", "aria-hidden": "true" }),
4402
+ unread > 0 && /* @__PURE__ */ jsx74("span", { className: "absolute -right-1.5 -top-1.5 flex size-[17px] items-center justify-center rounded-full bg-bg-brand text-xs font-bold leading-none text-text-on-brand ring-2 ring-bg-surface", children: unread })
4403
+ ]
4404
+ }
4405
+ ) }),
4406
+ /* @__PURE__ */ jsxs41(PopoverContent, { align: "end", className: "w-[380px] overflow-hidden p-0", children: [
4407
+ /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between px-5 py-3", children: [
4408
+ /* @__PURE__ */ jsx74("span", { className: "text-sm font-bold text-text-primary", children: "Notification center" }),
4409
+ /* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-3", children: [
4410
+ /* @__PURE__ */ jsx74(
4411
+ "button",
4412
+ {
4413
+ type: "button",
4414
+ disabled: unread === 0,
4415
+ onClick: () => onMarkAllRead?.(),
4416
+ className: cn(
4417
+ "text-sm font-medium transition-colors",
4418
+ unread === 0 ? "cursor-default text-text-disabled" : "text-text-tertiary hover:text-text-primary"
4419
+ ),
4420
+ children: "Mark all read"
4421
+ }
4422
+ ),
4423
+ onOpenSettings && /* @__PURE__ */ jsx74(
4424
+ "button",
4425
+ {
4426
+ type: "button",
4427
+ "aria-label": "Notification settings",
4428
+ onClick: () => onOpenSettings(),
4429
+ className: "flex size-6 items-center justify-center rounded-md text-text-tertiary transition-colors hover:bg-bg-surface hover:text-text-primary",
4430
+ children: /* @__PURE__ */ jsx74(Settings, { className: "size-[15px]", "aria-hidden": "true" })
4431
+ }
4432
+ )
4433
+ ] })
4434
+ ] }),
4435
+ /* @__PURE__ */ jsx74("div", { className: "space-y-1.5 px-2 pb-2", children: rows.length === 0 ? /* @__PURE__ */ jsx74("p", { className: "px-3 py-12 text-center text-xs leading-relaxed text-text-disabled", children: "Nothing yet. Everything addressed to you lands here." }) : rows.map((item) => /* @__PURE__ */ jsx74(
4436
+ BellRow,
4437
+ {
4438
+ item,
4439
+ onItemClick,
4440
+ onActionClick,
4441
+ formatAge: age
4442
+ },
4443
+ item.id
4444
+ )) }),
4445
+ items.length > 0 && onOpenArchive && /* @__PURE__ */ jsx74(
4446
+ "button",
4447
+ {
4448
+ type: "button",
4449
+ onClick: () => onOpenArchive(),
4450
+ className: "flex w-full items-center justify-center px-5 py-2.5 text-sm font-medium text-text-brand transition-colors hover:bg-bg-surface",
4451
+ children: "Open notifications archive"
4452
+ }
4453
+ )
4454
+ ] })
4455
+ ] });
4456
+ }
4457
+ );
4458
+ NotificationBell.displayName = "NotificationBell";
4459
+
4460
+ // src/components/notification-center.tsx
4461
+ import * as React62 from "react";
4462
+ import { ArrowUpRight, Check as Check7, Search as Search2 } from "lucide-react";
4463
+ import { jsx as jsx75, jsxs as jsxs42 } from "react/jsx-runtime";
4464
+ var chipBase = "rounded-lg px-3 py-1.5 text-sm font-medium transition-colors";
4465
+ var chipOn = "bg-bg-brand-subtle text-text-brand";
4466
+ var chipOff = "bg-bg-elevated text-text-secondary hover:text-text-primary";
4467
+ function CenterRow({
4468
+ item,
4469
+ onItemClick,
4470
+ onDeepLinkClick,
4471
+ formatAge
4472
+ }) {
4473
+ const unread = !item.read;
4474
+ const age = item.createdAt ? formatAge(item.createdAt instanceof Date ? item.createdAt : new Date(item.createdAt)) : null;
4475
+ return /* @__PURE__ */ jsxs42("article", { className: "rounded-lg bg-bg-elevated px-4 py-3", children: [
4476
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2", children: [
4477
+ /* @__PURE__ */ jsx75("span", { className: "text-xs font-semibold uppercase tracking-[0.09em] text-text-secondary", children: item.source }),
4478
+ /* @__PURE__ */ jsx75(Badge, { variant: severityBadgeVariant(item.severity), children: severityLabels[item.severity] }),
4479
+ age && /* @__PURE__ */ jsx75("span", { className: "ml-auto shrink-0 text-xs tabular-nums text-text-tertiary", children: age })
4480
+ ] }),
4481
+ /* @__PURE__ */ jsx75(
4482
+ "button",
4483
+ {
4484
+ type: "button",
4485
+ onClick: () => onItemClick?.(item),
4486
+ className: cn(
4487
+ "mt-1 block text-left text-sm leading-snug underline-offset-2 hover:underline",
4488
+ unread ? "font-semibold text-text-primary" : "font-medium text-text-secondary"
4489
+ ),
4490
+ children: item.title
4491
+ }
4492
+ ),
4493
+ item.body && /* @__PURE__ */ jsx75("p", { className: "mt-0.5 text-sm leading-snug text-text-secondary", children: item.body }),
4494
+ (item.receipt || item.deepLink) && /* @__PURE__ */ jsxs42("div", { className: "mt-2 flex flex-wrap items-center gap-x-4 gap-y-1.5", children: [
4495
+ item.receipt && /* @__PURE__ */ jsxs42("span", { className: "inline-flex items-center gap-1.5 text-sm text-text-tertiary", children: [
4496
+ /* @__PURE__ */ jsx75(Check7, { className: "size-3 shrink-0 text-text-success", "aria-hidden": "true" }),
4497
+ item.receipt
4498
+ ] }),
4499
+ item.deepLink && /* @__PURE__ */ jsxs42(
4500
+ "button",
4501
+ {
4502
+ type: "button",
4503
+ onClick: () => onDeepLinkClick?.(item),
4504
+ className: "inline-flex items-center gap-1 text-sm font-medium text-text-brand transition-colors hover:text-text-primary",
4505
+ children: [
4506
+ item.deepLink.label,
4507
+ /* @__PURE__ */ jsx75(ArrowUpRight, { className: "size-3", "aria-hidden": "true" })
4508
+ ]
4509
+ }
4510
+ )
4511
+ ] })
4512
+ ] });
4513
+ }
4514
+ var NotificationCenter = React62.forwardRef(
4515
+ ({
4516
+ items,
4517
+ title = "Notifications",
4518
+ description,
4519
+ sources,
4520
+ products,
4521
+ searchable = true,
4522
+ pageSize = 20,
4523
+ onItemClick,
4524
+ onDeepLinkClick,
4525
+ onMarkAllRead,
4526
+ formatAge,
4527
+ className
4528
+ }, ref) => {
4529
+ const [status, setStatus] = React62.useState("all");
4530
+ const [source, setSource] = React62.useState("all");
4531
+ const [product, setProduct] = React62.useState("all");
4532
+ const [query, setQuery] = React62.useState("");
4533
+ const [limit, setLimit] = React62.useState(pageSize);
4534
+ const age = React62.useCallback(
4535
+ (createdAt) => formatAge ? formatAge(createdAt) : formatRelativeAge(createdAt),
4536
+ [formatAge]
4537
+ );
4538
+ const sourceChips = React62.useMemo(
4539
+ () => sources ?? Array.from(new Set(items.map((n) => n.source))),
4540
+ [sources, items]
4541
+ );
4542
+ const q = query.trim().toLowerCase();
4543
+ const matched = items.filter((n) => status === "all" || !n.read).filter((n) => source === "all" || n.source === source).filter((n) => product === "all" || n.product === product).filter(
4544
+ (n) => q === "" || n.title.toLowerCase().includes(q) || (n.body ?? "").toLowerCase().includes(q) || n.source.toLowerCase().includes(q)
4545
+ );
4546
+ const shown = matched.slice(0, limit);
4547
+ const remaining = matched.length - shown.length;
4548
+ const filtering = q !== "" || status !== "all" || source !== "all" || product !== "all";
4549
+ return /* @__PURE__ */ jsxs42("div", { ref, className: cn("mx-auto max-w-[560px]", className), children: [
4550
+ /* @__PURE__ */ jsxs42("div", { className: "mb-4 flex items-start gap-4", children: [
4551
+ /* @__PURE__ */ jsxs42("div", { className: "min-w-0 flex-1", children: [
4552
+ /* @__PURE__ */ jsx75("h1", { className: "mb-1.5 text-2xl font-semibold tracking-tight text-text-primary", children: title }),
4553
+ description && /* @__PURE__ */ jsx75("p", { className: "text-sm text-text-tertiary", children: description })
4554
+ ] }),
4555
+ onMarkAllRead && /* @__PURE__ */ jsx75(
4556
+ "button",
4557
+ {
4558
+ type: "button",
4559
+ onClick: () => onMarkAllRead(),
4560
+ className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors hover:text-text-primary",
4561
+ children: "Read all"
4562
+ }
4563
+ )
4564
+ ] }),
4565
+ searchable && /* @__PURE__ */ jsxs42("div", { className: "mb-3 flex items-center gap-2 rounded-lg bg-bg-elevated px-3 py-2", children: [
4566
+ /* @__PURE__ */ jsx75(Search2, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
4567
+ /* @__PURE__ */ jsx75(
4568
+ "input",
4569
+ {
4570
+ type: "text",
4571
+ value: query,
4572
+ onChange: (e) => setQuery(e.target.value),
4573
+ placeholder: "Search notifications",
4574
+ className: "w-full bg-transparent text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none"
4575
+ }
4576
+ )
4577
+ ] }),
4578
+ /* @__PURE__ */ jsxs42("div", { className: "mb-2 flex flex-wrap gap-1.5", children: [
4579
+ /* @__PURE__ */ jsx75(
4580
+ "button",
4581
+ {
4582
+ type: "button",
4583
+ onClick: () => setStatus("all"),
4584
+ className: cn(chipBase, status === "all" ? chipOn : chipOff),
4585
+ children: "All"
4586
+ }
4587
+ ),
4588
+ /* @__PURE__ */ jsx75(
4589
+ "button",
4590
+ {
4591
+ type: "button",
4592
+ onClick: () => setStatus("unread"),
4593
+ className: cn(chipBase, status === "unread" ? chipOn : chipOff),
4594
+ children: "Unread"
4595
+ }
4596
+ )
4597
+ ] }),
4598
+ /* @__PURE__ */ jsxs42("div", { className: "mb-2 flex flex-wrap gap-1.5", children: [
4599
+ /* @__PURE__ */ jsx75(
4600
+ "button",
4601
+ {
4602
+ type: "button",
4603
+ onClick: () => setSource("all"),
4604
+ className: cn(chipBase, source === "all" ? chipOn : chipOff),
4605
+ children: "All sources"
4606
+ }
4607
+ ),
4608
+ sourceChips.map((s) => /* @__PURE__ */ jsx75(
4609
+ "button",
4610
+ {
4611
+ type: "button",
4612
+ onClick: () => setSource(s),
4613
+ className: cn(chipBase, source === s ? chipOn : chipOff),
4614
+ children: s
4615
+ },
4616
+ s
4617
+ ))
4618
+ ] }),
4619
+ products && products.length > 0 && /* @__PURE__ */ jsxs42("div", { className: "mb-4 flex flex-wrap gap-1.5", children: [
4620
+ /* @__PURE__ */ jsx75(
4621
+ "button",
4622
+ {
4623
+ type: "button",
4624
+ onClick: () => setProduct("all"),
4625
+ className: cn(chipBase, product === "all" ? chipOn : chipOff),
4626
+ children: "All products"
4627
+ }
4628
+ ),
4629
+ products.map((p) => /* @__PURE__ */ jsx75(
4630
+ "button",
4631
+ {
4632
+ type: "button",
4633
+ onClick: () => setProduct(p.id),
4634
+ className: cn(chipBase, product === p.id ? chipOn : chipOff),
4635
+ children: p.label
4636
+ },
4637
+ p.id
4638
+ ))
4639
+ ] }),
4640
+ shown.length === 0 ? /* @__PURE__ */ jsx75("p", { className: "rounded-xl bg-bg-elevated px-4 py-10 text-center text-sm leading-relaxed text-text-disabled", children: filtering ? "Nothing matches." : "Nothing here yet. Everything addressed to you lands here." }) : /* @__PURE__ */ jsxs42("div", { className: "flex flex-col gap-1.5", children: [
4641
+ shown.map((item) => /* @__PURE__ */ jsx75(
4642
+ CenterRow,
4643
+ {
4644
+ item,
4645
+ onItemClick,
4646
+ onDeepLinkClick,
4647
+ formatAge: age
4648
+ },
4649
+ item.id
4650
+ )),
4651
+ remaining > 0 && /* @__PURE__ */ jsxs42(
4652
+ "button",
4653
+ {
4654
+ type: "button",
4655
+ onClick: () => setLimit((l) => l + pageSize),
4656
+ className: "mt-1 rounded-lg bg-bg-elevated px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors hover:bg-bg-surface hover:text-text-primary",
4657
+ children: [
4658
+ "Load ",
4659
+ remaining,
4660
+ " more"
4661
+ ]
4662
+ }
4663
+ )
4664
+ ] })
4665
+ ] });
4666
+ }
4667
+ );
4668
+ NotificationCenter.displayName = "NotificationCenter";
4669
+
4670
+ // src/components/notification-settings.tsx
4671
+ import * as React63 from "react";
4672
+ import { Moon as Moon2, Plus as Plus2, Volume2 } from "lucide-react";
4673
+ import { Fragment as Fragment9, jsx as jsx76, jsxs as jsxs43 } from "react/jsx-runtime";
4674
+ var THRESHOLDS = [
4675
+ ["everything", "Everything"],
4676
+ ["important", "Important"],
4677
+ ["critical only", "Critical only"]
4678
+ ];
4679
+ var DEFAULT_KEY = "default";
4680
+ function ThresholdControl({
4681
+ label,
4682
+ value,
4683
+ onChange
4684
+ }) {
4685
+ return /* @__PURE__ */ jsx76(
4686
+ "span",
4687
+ {
4688
+ role: "group",
4689
+ "aria-label": `Interrupt me for ${label}`,
4690
+ className: "inline-flex shrink-0 overflow-hidden rounded-md bg-bg-primary",
4691
+ children: THRESHOLDS.map(([threshold, text]) => /* @__PURE__ */ jsx76(
4692
+ "button",
4693
+ {
4694
+ type: "button",
4695
+ "aria-pressed": value === threshold,
4696
+ onClick: () => onChange(threshold),
4697
+ className: cn(
4698
+ "px-3 py-1.5 text-sm font-semibold transition-colors",
4699
+ value === threshold ? "bg-bg-brand-subtle text-text-brand" : "text-text-tertiary hover:text-text-primary"
4700
+ ),
4701
+ children: text
4702
+ },
4703
+ threshold
4704
+ ))
4705
+ }
4706
+ );
4707
+ }
4708
+ var NotificationSettings = React63.forwardRef(
4709
+ ({
4710
+ subscriptions,
4711
+ value,
4712
+ onChange,
4713
+ products,
4714
+ soundEnabled,
4715
+ onSoundEnabledChange,
4716
+ mutes = [],
4717
+ onUnmute,
4718
+ pushSlot,
4719
+ className
4720
+ }, ref) => {
4721
+ const [tab, setTab] = React63.useState(DEFAULT_KEY);
4722
+ const isDefault = tab === DEFAULT_KEY;
4723
+ const defaults = value[DEFAULT_KEY] ?? { thresholds: {} };
4724
+ const customized = !isDefault && Object.prototype.hasOwnProperty.call(value, tab);
4725
+ const active = customized ? value[tab] : defaults;
4726
+ const productLabel = products?.find((p) => p.id === tab)?.label ?? tab;
4727
+ const setThreshold = (id, threshold) => {
4728
+ const key = isDefault ? DEFAULT_KEY : tab;
4729
+ const base2 = value[key] ?? defaults;
4730
+ onChange({ ...value, [key]: { thresholds: { ...base2.thresholds, [id]: threshold } } });
4731
+ };
4732
+ const customize = () => onChange({ ...value, [tab]: { thresholds: { ...defaults.thresholds } } });
4733
+ const resetToDefault = () => {
4734
+ const next = { ...value };
4735
+ delete next[tab];
4736
+ onChange(next);
4737
+ };
4738
+ const scopeGroup = (scope) => {
4739
+ const rows = subscriptions.filter((s) => s.scope === scope);
4740
+ if (rows.length === 0) return null;
4741
+ return /* @__PURE__ */ jsxs43("div", { children: [
4742
+ /* @__PURE__ */ jsx76("p", { className: "mb-1.5 px-0.5 text-xs font-bold uppercase tracking-wider text-text-tertiary", children: scope === "product" ? "This product" : "Organization" }),
4743
+ /* @__PURE__ */ jsx76("div", { className: "space-y-2", children: rows.map((sub) => /* @__PURE__ */ jsxs43(
4744
+ "div",
4745
+ {
4746
+ className: "flex items-center gap-4 rounded-xl bg-bg-elevated px-4 py-3",
4747
+ children: [
4748
+ /* @__PURE__ */ jsx76("p", { className: "min-w-0 flex-1 text-sm font-semibold text-text-primary", children: sub.name }),
4749
+ /* @__PURE__ */ jsx76(
4750
+ ThresholdControl,
4751
+ {
4752
+ label: sub.name,
4753
+ value: active.thresholds[sub.id] ?? "important",
4754
+ onChange: (t) => setThreshold(sub.id, t)
4755
+ }
4756
+ )
4757
+ ]
4758
+ },
4759
+ sub.id
4760
+ )) })
4761
+ ] }, scope);
4762
+ };
4763
+ return /* @__PURE__ */ jsxs43("div", { ref, className: cn("space-y-5", className), children: [
4764
+ products && products.length > 0 && /* @__PURE__ */ jsxs43("div", { children: [
4765
+ /* @__PURE__ */ jsx76("p", { className: "mb-2 px-0.5 text-xs font-bold uppercase tracking-wider text-text-tertiary", children: "Preferences for" }),
4766
+ /* @__PURE__ */ jsx76("div", { className: "flex flex-wrap gap-2", children: [{ id: DEFAULT_KEY, label: "Default" }, ...products].map((t) => /* @__PURE__ */ jsxs43(
4767
+ "button",
4768
+ {
4769
+ type: "button",
4770
+ onClick: () => setTab(t.id),
4771
+ className: cn(
4772
+ "flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-semibold transition-colors",
4773
+ tab === t.id ? "bg-bg-brand-subtle text-text-brand" : "bg-bg-elevated text-text-tertiary hover:text-text-primary"
4774
+ ),
4775
+ children: [
4776
+ t.label,
4777
+ t.id !== DEFAULT_KEY && Object.prototype.hasOwnProperty.call(value, t.id) && /* @__PURE__ */ jsx76("span", { className: "size-1.5 rounded-full bg-bg-brand", "aria-label": "customized" })
4778
+ ]
4779
+ },
4780
+ t.id
4781
+ )) })
4782
+ ] }),
4783
+ isDefault ? /* @__PURE__ */ jsxs43(Fragment9, { children: [
4784
+ /* @__PURE__ */ jsx76("p", { className: "text-sm leading-relaxed text-text-secondary", children: "Your defaults, applied to every product unless you customize one. Everything addressed to you always lands in the in-app record; that cannot be turned off." }),
4785
+ /* @__PURE__ */ jsxs43(Card, { className: "border-none bg-bg-elevated p-5", children: [
4786
+ /* @__PURE__ */ jsx76("p", { className: "mb-1.5 text-xs font-bold uppercase tracking-wide text-text-tertiary", children: "Push to" }),
4787
+ /* @__PURE__ */ jsx76("p", { className: "mb-3 text-sm leading-relaxed text-text-secondary", children: "Forward notifications beyond the in-app record to a connected integration." }),
4788
+ pushSlot ?? /* @__PURE__ */ jsx76("div", { className: "rounded-lg bg-bg-surface px-4 py-6 text-center", children: /* @__PURE__ */ jsx76("p", { className: "text-sm text-text-tertiary", children: "No integrations connected." }) })
4789
+ ] }),
4790
+ mutes.length > 0 && /* @__PURE__ */ jsxs43("div", { children: [
4791
+ /* @__PURE__ */ jsx76("p", { className: "mb-1.5 px-0.5 text-xs font-bold uppercase tracking-wider text-text-tertiary", children: "Muted" }),
4792
+ /* @__PURE__ */ jsx76(Card, { className: "border-none bg-bg-elevated p-2", children: mutes.map((m) => /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-3 rounded-lg px-3 py-2.5", children: [
4793
+ /* @__PURE__ */ jsx76(Moon2, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
4794
+ /* @__PURE__ */ jsxs43("div", { className: "min-w-0 flex-1", children: [
4795
+ /* @__PURE__ */ jsx76("p", { className: "text-sm font-medium text-text-primary", children: m.source }),
4796
+ /* @__PURE__ */ jsxs43("p", { className: "text-sm text-text-tertiary", children: [
4797
+ "Muted \u2014 ",
4798
+ m.label,
4799
+ ". Critical still comes through."
4800
+ ] })
4801
+ ] }),
4802
+ /* @__PURE__ */ jsx76(
4803
+ "button",
4804
+ {
4805
+ type: "button",
4806
+ onClick: () => onUnmute?.(m.source),
4807
+ className: "rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors hover:bg-bg-surface",
4808
+ children: "Unmute"
4809
+ }
4810
+ )
4811
+ ] }, m.source)) })
4812
+ ] }),
4813
+ scopeGroup("product"),
4814
+ scopeGroup("org"),
4815
+ onSoundEnabledChange && /* @__PURE__ */ jsx76(Card, { className: "border-none bg-bg-elevated p-4", children: /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-3", children: [
4816
+ /* @__PURE__ */ jsx76(Volume2, { className: "size-4 text-text-tertiary", "aria-hidden": "true" }),
4817
+ /* @__PURE__ */ jsxs43("div", { className: "flex-1", children: [
4818
+ /* @__PURE__ */ jsx76("p", { className: "text-sm font-medium text-text-primary", children: "Notification sound" }),
4819
+ /* @__PURE__ */ jsx76("p", { className: "text-sm text-text-tertiary", children: "Play a tone when a notification arrives. Critical always chimes." })
4820
+ ] }),
4821
+ /* @__PURE__ */ jsx76(
4822
+ Switch,
4823
+ {
4824
+ checked: soundEnabled ?? false,
4825
+ onCheckedChange: onSoundEnabledChange,
4826
+ "aria-label": "Notification sound"
4827
+ }
4828
+ )
4829
+ ] }) })
4830
+ ] }) : !customized ? /* @__PURE__ */ jsxs43(Card, { className: "border-none bg-bg-elevated p-8 text-center", children: [
4831
+ /* @__PURE__ */ jsxs43("p", { className: "text-sm font-semibold text-text-primary", children: [
4832
+ productLabel,
4833
+ " follows your Default preferences."
4834
+ ] }),
4835
+ /* @__PURE__ */ jsx76("p", { className: "mx-auto mt-1.5 max-w-[360px] text-sm leading-relaxed text-text-tertiary", children: "Interrupt thresholds, sound and forwarding all come from Default. Opt in to give this product its own interrupt thresholds." }),
4836
+ /* @__PURE__ */ jsxs43(
4837
+ "button",
4838
+ {
4839
+ type: "button",
4840
+ onClick: customize,
4841
+ className: "mt-5 inline-flex items-center gap-1.5 rounded-lg bg-bg-brand px-3.5 py-2 text-sm font-semibold text-text-on-brand transition-colors hover:bg-bg-brand-hover",
4842
+ children: [
4843
+ /* @__PURE__ */ jsx76(Plus2, { className: "size-4", "aria-hidden": "true" }),
4844
+ " Customize for ",
4845
+ productLabel
4846
+ ]
4847
+ }
4848
+ )
4849
+ ] }) : /* @__PURE__ */ jsxs43(Fragment9, { children: [
4850
+ /* @__PURE__ */ jsx76(Card, { className: "border-none bg-bg-brand-subtle p-3.5", children: /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-3", children: [
4851
+ /* @__PURE__ */ jsxs43("div", { className: "min-w-0 flex-1", children: [
4852
+ /* @__PURE__ */ jsxs43("p", { className: "text-sm font-semibold text-text-brand", children: [
4853
+ "Custom preferences for ",
4854
+ productLabel
4855
+ ] }),
4856
+ /* @__PURE__ */ jsx76("p", { className: "text-sm leading-relaxed text-text-secondary", children: "Only the interrupt thresholds below differ. Sound and forwarding follow Default." })
4857
+ ] }),
4858
+ /* @__PURE__ */ jsx76(
4859
+ "button",
4860
+ {
4861
+ type: "button",
4862
+ onClick: resetToDefault,
4863
+ className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors hover:text-text-danger",
4864
+ children: "Reset to Default"
4865
+ }
4866
+ )
4867
+ ] }) }),
4868
+ scopeGroup("product")
4869
+ ] })
4870
+ ] });
4871
+ }
4872
+ );
4873
+ NotificationSettings.displayName = "NotificationSettings";
3844
4874
  export {
3845
4875
  Accordion,
3846
4876
  AccordionContent,
@@ -3889,6 +4919,8 @@ export {
3889
4919
  CarouselNext,
3890
4920
  CarouselPrevious,
3891
4921
  Checkbox,
4922
+ Code,
4923
+ CodeBlock,
3892
4924
  Col,
3893
4925
  Collapsible,
3894
4926
  CollapsibleContent2 as CollapsibleContent,
@@ -4009,6 +5041,10 @@ export {
4009
5041
  NavigationMenuList,
4010
5042
  NavigationMenuTrigger,
4011
5043
  NavigationMenuViewport,
5044
+ NotificationBell,
5045
+ NotificationCenter,
5046
+ NotificationSettings,
5047
+ OrgProductSwitcher,
4012
5048
  Pagination,
4013
5049
  PaginationContent,
4014
5050
  PaginationEllipsis,
@@ -4044,6 +5080,7 @@ export {
4044
5080
  SidebarNav,
4045
5081
  SidebarNavLink,
4046
5082
  SidebarProductHeader,
5083
+ SignInScreen,
4047
5084
  Skeleton,
4048
5085
  Slider,
4049
5086
  StatCard,
@@ -4076,9 +5113,13 @@ export {
4076
5113
  badgeVariants,
4077
5114
  buttonVariants,
4078
5115
  cn,
5116
+ formatRelativeAge,
4079
5117
  isKnownExtensionIcon,
5118
+ isNotificationSettled,
4080
5119
  navigationMenuTriggerStyle,
4081
5120
  segmentChipVariants,
5121
+ severityBadgeVariant,
5122
+ severityLabels,
4082
5123
  statusDotVariants,
4083
5124
  toast,
4084
5125
  toggleVariants,