@lessly/ui 2.3.1 → 4.0.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
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  Button,
3
+ EntityRow,
3
4
  NavRow,
5
+ RailToggle,
4
6
  Sheet,
5
7
  SheetClose,
6
8
  SheetContent,
@@ -19,7 +21,7 @@ import {
19
21
  cn,
20
22
  useIsMobile,
21
23
  useSidebar
22
- } from "./chunk-CEXND5YW.js";
24
+ } from "./chunk-DYHP7W3X.js";
23
25
 
24
26
  // src/components/auto-height.tsx
25
27
  import * as React from "react";
@@ -82,9 +84,10 @@ var Card = React2.forwardRef(
82
84
  "div",
83
85
  {
84
86
  ref,
87
+ "data-slot": "card",
85
88
  title: tooltip,
86
89
  className: cn(
87
- "rounded-xl border border-border-subtle bg-bg-surface text-text-primary shadow-sm",
90
+ "rounded-xl border border-border-subtle bg-bg-overlay text-text-primary shadow-sm",
88
91
  variant === "list" && "overflow-hidden",
89
92
  variant === "nested" && "rounded-md bg-bg-secondary p-3 shadow-none",
90
93
  className
@@ -170,7 +173,7 @@ var DialogContent = React3.forwardRef(({ className, children, showClose = true,
170
173
  ...props,
171
174
  children: [
172
175
  children,
173
- showClose && /* @__PURE__ */ jsxs2(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm text-text-tertiary opacity-70 transition-opacity duration-fast hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-border-focus disabled:pointer-events-none", children: [
176
+ showClose && /* @__PURE__ */ jsxs2(DialogPrimitive.Close, { className: "absolute right-4 top-4 cursor-pointer rounded-sm text-text-tertiary opacity-70 transition-opacity duration-fast hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-border-focus disabled:pointer-events-none", children: [
174
177
  /* @__PURE__ */ jsx3(X, { className: "h-4 w-4" }),
175
178
  /* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
176
179
  ] })
@@ -231,10 +234,17 @@ var DropdownMenuTrigger = React4.forwardRef(({ variant = "bare", chevron = true,
231
234
  ...props,
232
235
  ...variant === "quiet" ? {
233
236
  className: cn(
234
- "inline-flex min-h-9 items-center gap-1.5 rounded-md px-2 py-1.5 text-sm hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
237
+ "inline-flex min-h-9 cursor-pointer items-center gap-1.5 rounded-md px-2 py-1.5 text-sm hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
235
238
  props.className
236
239
  )
237
- } : null,
240
+ } : (
241
+ // A trigger the call site styles is a control the call site drew, so the cursor its own
242
+ // guideline asks for comes with the class list rather than from four call sites remembering
243
+ // it (Guidelines/Controls/What the cursor says). A trigger given no className still renders
244
+ // with no `class` attribute at all, which is what `bare` promises and what the test below
245
+ // pins — and whatever it wraps through `asChild` carries its own.
246
+ props.className !== void 0 ? { className: cn("cursor-pointer", props.className) } : null
247
+ ),
238
248
  children: variant === "quiet" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
239
249
  children,
240
250
  chevron && /* @__PURE__ */ jsx4(ChevronDown, { className: "size-3.5 shrink-0 text-text-tertiary", "aria-hidden": true })
@@ -293,9 +303,10 @@ var DropdownMenuItem = React4.forwardRef(({ className, inset, variant = "default
293
303
  className: cn(
294
304
  "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
295
305
  inset && "pl-8",
296
- // Destructive reddens — wash and label — under the pointer or the keyboard, and drops the red
297
- // frame a destructive Button rests on, because a row repeated down a menu makes the whole menu
298
- // feel dangerous (Guidelines/Controls/Destructive actions). Only a dialog's confirm rests red.
306
+ // Destructive reddens — wash and label — under the pointer or the keyboard, and carries nothing
307
+ // at rest: it drops the frame and the wash a destructive Button rests on, because a row repeated
308
+ // down a menu makes the whole menu feel dangerous (Guidelines/Controls/Destructive actions).
309
+ // The opaque plate is a dialog's confirm alone.
299
310
  variant === "destructive" ? "focus:bg-bg-danger-subtle focus:text-text-danger focus:ring-border-danger" : "focus:ring-border-selected",
300
311
  className
301
312
  ),
@@ -479,7 +490,7 @@ import { cva as cva2 } from "class-variance-authority";
479
490
  import { Check as Check2 } from "lucide-react";
480
491
  import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
481
492
  var optionCardVariants = cva2(
482
- "flex w-full items-center gap-3 rounded-lg border border-border-default p-3 text-left transition-colors duration-fast hover:bg-bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
493
+ "flex w-full cursor-pointer items-center gap-3 rounded-lg border border-border-default p-3 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
483
494
  {
484
495
  variants: {
485
496
  selected: {
@@ -523,7 +534,7 @@ var Medallion = React9.forwardRef(
523
534
  "aria-hidden": true,
524
535
  className: cn(
525
536
  "inline-flex size-12 shrink-0 items-center justify-center rounded-full border border-border-subtle",
526
- filled ? "border-transparent bg-text-primary text-text-inverse" : "bg-bg-secondary text-text-secondary",
537
+ filled ? "border-transparent bg-text-primary text-text-inverse" : "bg-bg-overlay text-text-secondary",
527
538
  className
528
539
  ),
529
540
  ...props,
@@ -535,11 +546,12 @@ Medallion.displayName = "Medallion";
535
546
 
536
547
  // src/components/page-header.tsx
537
548
  import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
538
- function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, id }) {
539
- if (Icon && !subtitle && !media && process.env.NODE_ENV !== "production") {
549
+ function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, size = "page", id }) {
550
+ const compact = size === "compact";
551
+ if (Icon && !subtitle && !media && !compact && process.env.NODE_ENV !== "production") {
540
552
  console.warn("PageHeader: `icon` needs a `subtitle` to render the medallion; medallion dropped.");
541
553
  }
542
- const leading = media ?? (Icon && subtitle ? /* @__PURE__ */ jsx10(Medallion, { icon: Icon, "data-slot": "page-header-medallion" }) : null);
554
+ const leading = media ?? (Icon && subtitle && !compact ? /* @__PURE__ */ jsx10(Medallion, { icon: Icon, "data-slot": "page-header-medallion" }) : null);
543
555
  const heading = /* @__PURE__ */ jsx10("h2", { id, className: "text-lg font-semibold text-text-primary", children: title });
544
556
  return /* @__PURE__ */ jsxs6("div", { className: "flex min-h-9 items-center gap-3", children: [
545
557
  leading,
@@ -548,7 +560,7 @@ function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, id })
548
560
  heading,
549
561
  badge
550
562
  ] }),
551
- subtitle && /* @__PURE__ */ jsx10("p", { className: "text-sm text-text-secondary", children: subtitle })
563
+ subtitle && !compact && /* @__PURE__ */ jsx10("p", { className: "text-sm text-text-secondary", children: subtitle })
552
564
  ] }),
553
565
  actions && /* @__PURE__ */ jsx10("div", { className: "ml-auto shrink-0", children: actions })
554
566
  ] });
@@ -653,8 +665,9 @@ function Select({
653
665
 
654
666
  // src/components/setting-row.tsx
655
667
  import * as React10 from "react";
668
+ import { Lock } from "lucide-react";
656
669
  import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
657
- var SettingRow = React10.forwardRef(function SettingRow2({ icon: Icon, label, description, labelTone = "primary", htmlFor, children, className, ...props }, ref) {
670
+ var SettingRow = React10.forwardRef(function SettingRow2({ icon: Icon, label, description, labelTone = "primary", locked, htmlFor, children, className, ...props }, ref) {
658
671
  const Label5 = htmlFor ? "label" : "span";
659
672
  const quiet = labelTone === "secondary";
660
673
  return /* @__PURE__ */ jsxs9(
@@ -694,7 +707,10 @@ var SettingRow = React10.forwardRef(function SettingRow2({ icon: Icon, label, de
694
707
  description && /* @__PURE__ */ jsx13("span", { className: "block text-xs text-text-tertiary", children: description })
695
708
  ] })
696
709
  ] }),
697
- /* @__PURE__ */ jsx13("span", { className: "flex shrink-0 items-center", children })
710
+ /* @__PURE__ */ jsxs9("span", { className: "flex shrink-0 items-center gap-2", children: [
711
+ locked && /* @__PURE__ */ jsx13(Lock, { className: "size-3.5 text-text-tertiary", "aria-hidden": "true" }),
712
+ children
713
+ ] })
698
714
  ]
699
715
  }
700
716
  );
@@ -724,7 +740,7 @@ function Switch({
724
740
  "data-testid": testId,
725
741
  disabled,
726
742
  onClick: () => onCheckedChange(!checked),
727
- className: `relative inline-flex h-6 w-10 shrink-0 cursor-pointer rounded-full transition-colors duration-fast outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface ${checked ? "bg-text-brand" : "bg-bg-surface"} ${disabled ? "cursor-not-allowed opacity-50" : ""} ${className}`,
743
+ className: `relative inline-flex h-6 w-10 shrink-0 rounded-full transition-colors duration-fast outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface ${checked ? "bg-text-brand" : "bg-bg-surface"} ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"} ${className}`,
728
744
  children: [
729
745
  /* @__PURE__ */ jsx14(
730
746
  "span",
@@ -764,7 +780,7 @@ var Checkbox = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__
764
780
  // A field takes the field border (`Guidelines/Look/Borders`, #417). No hover step and no
765
781
  // filled step: a 16px box's hover reading is the label beside it, and "answered" is already
766
782
  // the checked mark, which paints the whole box.
767
- "peer size-4 shrink-0 rounded-sm border border-field-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-400 data-[state=checked]:text-text-on-brand data-[state=checked]:border-blue-400",
783
+ "peer size-4 shrink-0 cursor-pointer rounded-sm border border-field-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-400 data-[state=checked]:text-text-on-brand data-[state=checked]:border-blue-400",
768
784
  className
769
785
  ),
770
786
  ...props,
@@ -786,7 +802,7 @@ var RadioGroupItem = React12.forwardRef(({ className, ...props }, ref) => /* @__
786
802
  ref,
787
803
  className: cn(
788
804
  // The same field edge a `Checkbox` takes, and for the same reasons (#417).
789
- "aspect-square size-4 rounded-full border border-field-border text-blue-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-blue-400",
805
+ "aspect-square size-4 cursor-pointer rounded-full border border-field-border text-blue-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-blue-400",
790
806
  className
791
807
  ),
792
808
  ...props,
@@ -825,7 +841,7 @@ var Slider = React14.forwardRef(({ className, ...props }, ref) => {
825
841
  SliderPrimitive.Root,
826
842
  {
827
843
  ref,
828
- className: cn("relative flex w-full touch-none select-none items-center", className),
844
+ className: cn("relative flex w-full cursor-pointer touch-none select-none items-center", className),
829
845
  ...props,
830
846
  children: [
831
847
  /* @__PURE__ */ jsx18(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-bg-secondary", children: /* @__PURE__ */ jsx18(SliderPrimitive.Range, { className: "absolute h-full bg-blue-400" }) }),
@@ -848,7 +864,7 @@ import * as TogglePrimitive from "@radix-ui/react-toggle";
848
864
  import { cva as cva3 } from "class-variance-authority";
849
865
  import { jsx as jsx19 } from "react/jsx-runtime";
850
866
  var toggleVariants = cva3(
851
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium data-[state=on]:font-semibold text-text-secondary transition-colors duration-fast focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
867
+ "inline-flex cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium data-[state=on]:font-semibold text-text-secondary transition-colors duration-fast focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
852
868
  {
853
869
  variants: {
854
870
  /**
@@ -1518,11 +1534,11 @@ var badgeVariants = cva4(
1518
1534
  default: "border-transparent bg-blue-400 text-text-on-brand",
1519
1535
  secondary: "border-transparent bg-bg-secondary text-text-primary",
1520
1536
  outline: "border-border-default text-text-primary",
1521
- status: "border-transparent bg-bg-sunken text-text-primary",
1537
+ status: "border-border-subtle bg-bg-overlay text-text-primary",
1522
1538
  destructive: "border-transparent bg-bg-danger text-text-on-danger",
1523
1539
  "danger-subtle": "border-transparent bg-bg-danger-subtle text-text-danger",
1524
1540
  "warning-subtle": "border-transparent bg-bg-warning-subtle text-text-warning",
1525
- "neutral-subtle": "border-transparent bg-bg-sunken text-text-tertiary",
1541
+ "neutral-subtle": "border-border-subtle bg-bg-overlay text-text-tertiary",
1526
1542
  success: "border-transparent bg-bg-success text-text-on-success",
1527
1543
  warning: "border-transparent bg-bg-warning text-text-on-warning"
1528
1544
  }
@@ -1662,7 +1678,7 @@ var GLYPH_SIZE = {
1662
1678
  lg: "size-6"
1663
1679
  };
1664
1680
  var TONE = {
1665
- neutral: "bg-bg-secondary text-text-secondary",
1681
+ neutral: "bg-bg-overlay text-text-secondary",
1666
1682
  teal: "bg-bg-teal-subtle text-text-teal",
1667
1683
  violet: "bg-bg-violet-subtle text-text-violet",
1668
1684
  rose: "bg-bg-rose-subtle text-text-rose"
@@ -1728,12 +1744,12 @@ function GlyphAvatar({ kind, size = "sm", label }) {
1728
1744
  // src/components/entity-tile.tsx
1729
1745
  import * as React28 from "react";
1730
1746
  import { jsx as jsx35 } from "react/jsx-runtime";
1731
- function EntityTile({ name, glyph, src, size = "sm", label }) {
1732
- const tone = !glyph && name ? tintFor(name) : "neutral";
1747
+ function EntityTile({ name, glyph, tone = "auto", src, size = "sm", label }) {
1748
+ const painted = tone === "auto" && !glyph && name ? tintFor(name) : "neutral";
1733
1749
  const sizedGlyph = React28.isValidElement(glyph) ? React28.cloneElement(glyph, {
1734
1750
  className: cn(GLYPH_SIZE[size], glyph.props.className)
1735
1751
  }) : glyph;
1736
- return /* @__PURE__ */ jsx35(Mark, { shape: "square", size, tone, src, label, children: sizedGlyph ?? (name ? initialOf(name) : null) });
1752
+ return /* @__PURE__ */ jsx35(Mark, { shape: "square", size, tone: painted, src, label, children: sizedGlyph ?? (name ? initialOf(name) : null) });
1737
1753
  }
1738
1754
 
1739
1755
  // src/components/separator.tsx
@@ -1804,7 +1820,7 @@ var TabsTrigger = React31.forwardRef(({ className, ...props }, ref) => /* @__PUR
1804
1820
  {
1805
1821
  ref,
1806
1822
  className: cn(
1807
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-bg-sunken data-[state=active]:font-semibold data-[state=active]:text-text-primary",
1823
+ "inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-bg-sunken data-[state=active]:font-semibold data-[state=active]:text-text-primary",
1808
1824
  className
1809
1825
  ),
1810
1826
  ...props
@@ -1844,7 +1860,7 @@ var AccordionTrigger = React32.forwardRef(({ className, children, ...props }, re
1844
1860
  {
1845
1861
  ref,
1846
1862
  className: cn(
1847
- "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all duration-fast hover:underline [&[data-state=open]>svg]:rotate-180",
1863
+ "flex flex-1 cursor-pointer items-center justify-between py-4 text-sm font-medium transition-all duration-fast hover:underline [&[data-state=open]>svg]:rotate-180",
1848
1864
  className
1849
1865
  ),
1850
1866
  ...props,
@@ -1927,14 +1943,14 @@ import * as React35 from "react";
1927
1943
  import { cva as cva5 } from "class-variance-authority";
1928
1944
  import { jsx as jsx42, jsxs as jsxs21 } from "react/jsx-runtime";
1929
1945
  var alertVariants = cva5(
1930
- "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
1946
+ "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:size-4",
1931
1947
  {
1932
1948
  variants: {
1933
1949
  variant: {
1934
- default: "bg-bg-elevated border-border-subtle text-text-primary",
1935
- destructive: "bg-bg-danger border-border-danger text-text-on-danger",
1936
- success: "bg-bg-success border-border-success text-text-on-success",
1937
- warning: "bg-bg-warning border-border-warning text-text-on-warning"
1950
+ default: "bg-bg-elevated border-border-default text-text-primary [&>svg]:text-text-secondary",
1951
+ destructive: "bg-bg-danger-subtle border-border-danger text-text-primary [&>svg]:text-text-danger",
1952
+ success: "bg-bg-success-subtle border-border-success text-text-primary [&>svg]:text-text-success",
1953
+ warning: "bg-bg-warning-subtle border-border-warning text-text-primary [&>svg]:text-text-warning"
1938
1954
  }
1939
1955
  },
1940
1956
  defaultVariants: { variant: "default" }
@@ -1963,7 +1979,7 @@ var AlertTitle = React35.forwardRef(({ className, ...props }, ref) => /* @__PURE
1963
1979
  "h5",
1964
1980
  {
1965
1981
  ref,
1966
- className: cn("mb-1 font-medium leading-none tracking-tight", className),
1982
+ className: cn("mb-1 text-sm font-semibold leading-none tracking-tight", className),
1967
1983
  ...props
1968
1984
  }
1969
1985
  ));
@@ -1972,7 +1988,7 @@ var AlertDescription = React35.forwardRef(({ className, ...props }, ref) => /* @
1972
1988
  "div",
1973
1989
  {
1974
1990
  ref,
1975
- className: cn("text-sm [&_p]:leading-relaxed", className),
1991
+ className: cn("text-sm text-text-secondary [&_p]:leading-relaxed", className),
1976
1992
  ...props
1977
1993
  }
1978
1994
  ));
@@ -2137,9 +2153,9 @@ PaginationEllipsis.displayName = "PaginationEllipsis";
2137
2153
 
2138
2154
  // src/components/command.tsx
2139
2155
  import * as React38 from "react";
2140
- import { Command as CommandPrimitive } from "cmdk";
2156
+ import { Command as CommandPrimitive, useCommandState } from "cmdk";
2141
2157
  import { Search } from "lucide-react";
2142
- import { jsx as jsx45, jsxs as jsxs24 } from "react/jsx-runtime";
2158
+ import { Fragment as Fragment2, jsx as jsx45, jsxs as jsxs24 } from "react/jsx-runtime";
2143
2159
  var Command = React38.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx45(
2144
2160
  CommandPrimitive,
2145
2161
  {
@@ -2152,7 +2168,58 @@ var Command = React38.forwardRef(({ className, ...props }, ref) => /* @__PURE__
2152
2168
  }
2153
2169
  ));
2154
2170
  Command.displayName = CommandPrimitive.displayName;
2155
- var CommandDialog = ({ children, ...props }) => /* @__PURE__ */ jsx45(Dialog, { ...props, children: /* @__PURE__ */ jsx45(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx45(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-text-tertiary [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children }) }) });
2171
+ var KeyCap = ({ children }) => /* @__PURE__ */ jsx45("kbd", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-sm border border-border-default bg-bg-elevated px-1 font-sans text-xs text-text-secondary", children });
2172
+ var CommandKeyHints = () => /* @__PURE__ */ jsx45("div", { className: "flex items-center gap-4 border-t border-border-subtle bg-bg-sunken px-3 py-2 text-xs text-text-tertiary", children: [[["\u2191", "\u2193"], "to navigate"], [["\u21B5"], "to select"]].map(([keys, verb]) => /* @__PURE__ */ jsxs24("span", { className: "flex items-center gap-1.5", children: [
2173
+ /* @__PURE__ */ jsx45("span", { className: "flex items-center gap-1", children: keys.map((key) => /* @__PURE__ */ jsx45(KeyCap, { children: key }, key)) }),
2174
+ " ",
2175
+ verb
2176
+ ] }, verb)) });
2177
+ var CommandKeyHintsSlot = ({ children }) => {
2178
+ const count = useCommandState((state) => state.filtered.count);
2179
+ return count > 0 ? /* @__PURE__ */ jsx45(Fragment2, { children }) : null;
2180
+ };
2181
+ var CommandDialog = ({
2182
+ children,
2183
+ groups,
2184
+ placeholder,
2185
+ empty,
2186
+ keyHints = /* @__PURE__ */ jsx45(CommandKeyHints, {}),
2187
+ shortcut = false,
2188
+ open,
2189
+ onOpenChange,
2190
+ ...props
2191
+ }) => {
2192
+ React38.useEffect(() => {
2193
+ if (!shortcut || !onOpenChange) return;
2194
+ const onKey = (e) => {
2195
+ if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
2196
+ e.preventDefault();
2197
+ onOpenChange(!open);
2198
+ }
2199
+ };
2200
+ document.addEventListener("keydown", onKey);
2201
+ return () => document.removeEventListener("keydown", onKey);
2202
+ }, [shortcut, open, onOpenChange]);
2203
+ return /* @__PURE__ */ jsx45(Dialog, { open, onOpenChange, ...props, children: /* @__PURE__ */ jsx45(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx45(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-text-tertiary [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children: groups ? /* @__PURE__ */ jsxs24(Fragment2, { children: [
2204
+ /* @__PURE__ */ jsx45(CommandInput, { placeholder }),
2205
+ /* @__PURE__ */ jsxs24(CommandList, { className: "max-h-[420px]", children: [
2206
+ /* @__PURE__ */ jsx45(CommandEmpty, { children: empty }),
2207
+ groups.map((group) => /* @__PURE__ */ jsx45(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsx45(
2208
+ CommandItem,
2209
+ {
2210
+ value: item.value ?? [group.heading, item.sub, item.label].filter(Boolean).join(" "),
2211
+ mark: item.mark,
2212
+ sub: item.sub,
2213
+ className: item.sub ? void 0 : "items-center",
2214
+ onSelect: item.onSelect,
2215
+ children: item.label
2216
+ },
2217
+ item.id ?? `${group.heading}:${String(item.label)}`
2218
+ )) }, group.heading))
2219
+ ] }),
2220
+ /* @__PURE__ */ jsx45(CommandKeyHintsSlot, { children: keyHints })
2221
+ ] }) : children }) }) });
2222
+ };
2156
2223
  var CommandInput = React38.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs24("div", { className: "flex items-center border-b border-border-subtle px-3", "cmdk-input-wrapper": "", children: [
2157
2224
  /* @__PURE__ */ jsx45(Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
2158
2225
  /* @__PURE__ */ jsx45(
@@ -2172,7 +2239,7 @@ var CommandList = React38.forwardRef(({ className, ...props }, ref) => /* @__PUR
2172
2239
  CommandPrimitive.List,
2173
2240
  {
2174
2241
  ref,
2175
- className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
2242
+ className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden pb-2", className),
2176
2243
  ...props
2177
2244
  }
2178
2245
  ));
@@ -2213,7 +2280,7 @@ var CommandItem = React38.forwardRef(
2213
2280
  {
2214
2281
  ref,
2215
2282
  className: cn(
2216
- "relative flex cursor-default select-none gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-bg-secondary data-[selected=true]:text-text-primary",
2283
+ "relative flex cursor-default select-none gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-[var(--hov-bg)] data-[selected=true]:text-text-primary",
2217
2284
  mark ? "items-start" : "items-center",
2218
2285
  className
2219
2286
  ),
@@ -2268,7 +2335,7 @@ var NavigationMenuList = React39.forwardRef(({ className, ...props }, ref) => /*
2268
2335
  NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
2269
2336
  var NavigationMenuItem = NavigationMenuPrimitive.Item;
2270
2337
  var navigationMenuTriggerStyle = cva6(
2271
- "group inline-flex h-10 w-max items-center justify-center rounded-md bg-bg-elevated px-4 py-2 text-sm font-medium transition-colors duration-fast hover:bg-bg-secondary hover:text-text-primary focus:bg-bg-secondary focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-bg-secondary"
2338
+ "group inline-flex h-10 w-max cursor-pointer items-center justify-center rounded-md bg-bg-elevated px-4 py-2 text-sm font-medium transition-colors duration-fast hover:bg-bg-secondary hover:text-text-primary focus:bg-bg-secondary focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-bg-secondary"
2272
2339
  );
2273
2340
  var NavigationMenuTrigger = React39.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs25(
2274
2341
  NavigationMenuPrimitive.Trigger,
@@ -2330,7 +2397,7 @@ var NavigationMenuIndicator = React39.forwardRef(({ className, ...props }, ref)
2330
2397
  NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;
2331
2398
 
2332
2399
  // src/hooks/useTheme.ts
2333
- import { useEffect as useEffect2, useState as useState2, useCallback } from "react";
2400
+ import { useEffect as useEffect3, useState as useState2, useCallback } from "react";
2334
2401
  var STORAGE_KEY = "lessly_theme";
2335
2402
  var THEMES = ["light", "dark", "system"];
2336
2403
  function parseStoredTheme(stored) {
@@ -2364,10 +2431,10 @@ function useTheme() {
2364
2431
  applyTheme(resolveTheme(newTheme));
2365
2432
  window.dispatchEvent(new CustomEvent("lessly-theme-change", { detail: newTheme }));
2366
2433
  }, []);
2367
- useEffect2(() => {
2434
+ useEffect3(() => {
2368
2435
  applyTheme(resolvedTheme);
2369
2436
  }, [resolvedTheme]);
2370
- useEffect2(() => {
2437
+ useEffect3(() => {
2371
2438
  const handler = (e) => {
2372
2439
  const newTheme = e.detail;
2373
2440
  setThemeState(newTheme);
@@ -2375,7 +2442,7 @@ function useTheme() {
2375
2442
  window.addEventListener("lessly-theme-change", handler);
2376
2443
  return () => window.removeEventListener("lessly-theme-change", handler);
2377
2444
  }, []);
2378
- useEffect2(() => {
2445
+ useEffect3(() => {
2379
2446
  if (theme !== "system") return;
2380
2447
  const mql = window.matchMedia("(prefers-color-scheme: light)");
2381
2448
  const handler = () => applyTheme(getSystemTheme());
@@ -2410,7 +2477,21 @@ var Toaster = ({ ...props }) => {
2410
2477
 
2411
2478
  // src/components/theme-toggle.tsx
2412
2479
  import { Sun, Moon } from "lucide-react";
2413
- import { jsx as jsx48 } from "react/jsx-runtime";
2480
+
2481
+ // src/components/top-bar-utilities.tsx
2482
+ import * as React40 from "react";
2483
+ import { jsx as jsx48, jsxs as jsxs26 } from "react/jsx-runtime";
2484
+ var topBarMarkClass = "relative flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-lg text-text-secondary transition-colors duration-fast hover:bg-[var(--hov-bg)] hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus [&>svg]:size-[18px]";
2485
+ var TopBarUtilities = React40.forwardRef(
2486
+ ({ items, className, ...props }, ref) => /* @__PURE__ */ jsx48("div", { ref, className: cn("flex items-center gap-1", className), ...props, children: items.map(({ name, icon, onClick }) => /* @__PURE__ */ jsxs26(Tooltip, { children: [
2487
+ /* @__PURE__ */ jsx48(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx48("button", { type: "button", className: topBarMarkClass, "aria-label": name, onClick, children: icon }) }),
2488
+ /* @__PURE__ */ jsx48(TooltipContent, { children: name })
2489
+ ] }, name)) })
2490
+ );
2491
+ TopBarUtilities.displayName = "TopBarUtilities";
2492
+
2493
+ // src/components/theme-toggle.tsx
2494
+ import { jsx as jsx49 } from "react/jsx-runtime";
2414
2495
  var icons = {
2415
2496
  light: Sun,
2416
2497
  dark: Moon
@@ -2420,14 +2501,15 @@ function ThemeToggle() {
2420
2501
  const Icon = icons[resolvedTheme];
2421
2502
  const next = resolvedTheme === "light" ? "dark" : "light";
2422
2503
  const label = theme === "system" ? `Following your device (${resolvedTheme}). Switch to ${next}.` : `Switch to ${next} theme`;
2423
- return /* @__PURE__ */ jsx48(
2504
+ return /* @__PURE__ */ jsx49(
2424
2505
  "button",
2425
2506
  {
2507
+ type: "button",
2426
2508
  onClick: () => setTheme(next),
2427
- className: "p-2 rounded-lg text-text-secondary hover:bg-bg-secondary transition-colors duration-fast",
2509
+ className: topBarMarkClass,
2428
2510
  "aria-label": label,
2429
2511
  title: label,
2430
- children: /* @__PURE__ */ jsx48(Icon, { className: "w-4 h-4" })
2512
+ children: /* @__PURE__ */ jsx49(Icon, {})
2431
2513
  }
2432
2514
  );
2433
2515
  }
@@ -2435,9 +2517,9 @@ function ThemeToggle() {
2435
2517
  // src/components/calendar.tsx
2436
2518
  import { ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight6 } from "lucide-react";
2437
2519
  import { DayPicker } from "react-day-picker";
2438
- import { jsx as jsx49 } from "react/jsx-runtime";
2520
+ import { jsx as jsx50 } from "react/jsx-runtime";
2439
2521
  function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
2440
- return /* @__PURE__ */ jsx49(
2522
+ return /* @__PURE__ */ jsx50(
2441
2523
  DayPicker,
2442
2524
  {
2443
2525
  showOutsideDays,
@@ -2495,7 +2577,7 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
2495
2577
  ...classNames
2496
2578
  },
2497
2579
  components: {
2498
- Chevron: ({ className: cls, orientation, ...rest }) => orientation === "left" ? /* @__PURE__ */ jsx49(ChevronLeft2, { className: cn("size-4", cls), ...rest }) : /* @__PURE__ */ jsx49(ChevronRight6, { className: cn("size-4", cls), ...rest })
2580
+ Chevron: ({ className: cls, orientation, ...rest }) => orientation === "left" ? /* @__PURE__ */ jsx50(ChevronLeft2, { className: cn("size-4", cls), ...rest }) : /* @__PURE__ */ jsx50(ChevronRight6, { className: cn("size-4", cls), ...rest })
2499
2581
  },
2500
2582
  ...props
2501
2583
  }
@@ -2504,9 +2586,9 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
2504
2586
  Calendar.displayName = "Calendar";
2505
2587
 
2506
2588
  // src/components/date-picker.tsx
2507
- import * as React40 from "react";
2589
+ import * as React41 from "react";
2508
2590
  import { Calendar as CalendarIcon } from "lucide-react";
2509
- import { jsx as jsx50, jsxs as jsxs26 } from "react/jsx-runtime";
2591
+ import { jsx as jsx51, jsxs as jsxs27 } from "react/jsx-runtime";
2510
2592
  var DEFAULT_FORMAT = {
2511
2593
  year: "numeric",
2512
2594
  month: "long",
@@ -2519,9 +2601,9 @@ function DatePicker({
2519
2601
  disabled,
2520
2602
  className
2521
2603
  }) {
2522
- const [open, setOpen] = React40.useState(false);
2523
- return /* @__PURE__ */ jsxs26(Popover, { open, onOpenChange: setOpen, children: [
2524
- /* @__PURE__ */ jsx50(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs26(
2604
+ const [open, setOpen] = React41.useState(false);
2605
+ return /* @__PURE__ */ jsxs27(Popover, { open, onOpenChange: setOpen, children: [
2606
+ /* @__PURE__ */ jsx51(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs27(
2525
2607
  Button,
2526
2608
  {
2527
2609
  type: "button",
@@ -2529,12 +2611,12 @@ function DatePicker({
2529
2611
  disabled,
2530
2612
  className: cn("w-[240px] justify-start gap-2 text-left font-regular", !value && "text-text-tertiary", className),
2531
2613
  children: [
2532
- /* @__PURE__ */ jsx50(CalendarIcon, { className: "size-4 shrink-0" }),
2614
+ /* @__PURE__ */ jsx51(CalendarIcon, { className: "size-4 shrink-0" }),
2533
2615
  value ? value.toLocaleDateString(void 0, DEFAULT_FORMAT) : placeholder
2534
2616
  ]
2535
2617
  }
2536
2618
  ) }),
2537
- /* @__PURE__ */ jsx50(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx50(
2619
+ /* @__PURE__ */ jsx51(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx51(
2538
2620
  Calendar,
2539
2621
  {
2540
2622
  mode: "single",
@@ -2551,20 +2633,20 @@ function DatePicker({
2551
2633
  DatePicker.displayName = "DatePicker";
2552
2634
 
2553
2635
  // src/components/add-picker.tsx
2554
- import * as React41 from "react";
2636
+ import * as React42 from "react";
2555
2637
  import { Plus } from "lucide-react";
2556
- import { jsx as jsx51, jsxs as jsxs27 } from "react/jsx-runtime";
2557
- var AddPicker = React41.forwardRef(
2638
+ import { jsx as jsx52, jsxs as jsxs28 } from "react/jsx-runtime";
2639
+ var AddPicker = React42.forwardRef(
2558
2640
  ({ label, noun, items, exclude, onPick, className }, ref) => {
2559
- const [open, setOpen] = React41.useState(false);
2560
- const [q, setQ] = React41.useState("");
2641
+ const [open, setOpen] = React42.useState(false);
2642
+ const [q, setQ] = React42.useState("");
2561
2643
  const taken = exclude ?? [];
2562
2644
  const needle = q.toLowerCase();
2563
2645
  const matches = items.filter(
2564
2646
  (item) => !taken.includes(item.id) && (item.name.toLowerCase().includes(needle) || !!item.sub?.toLowerCase().includes(needle))
2565
2647
  );
2566
2648
  const search = items.length > 1 ? `Search ${items.length} ${noun}` : `Search ${noun}`;
2567
- return /* @__PURE__ */ jsxs27(
2649
+ return /* @__PURE__ */ jsxs28(
2568
2650
  Popover,
2569
2651
  {
2570
2652
  open,
@@ -2573,15 +2655,15 @@ var AddPicker = React41.forwardRef(
2573
2655
  if (!next) setQ("");
2574
2656
  },
2575
2657
  children: [
2576
- /* @__PURE__ */ jsx51(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs27(Button, { ref, variant: "ghost", size: "xs", className: cn("shrink-0", className), children: [
2577
- /* @__PURE__ */ jsx51(Plus, { className: "size-4", "aria-hidden": true }),
2658
+ /* @__PURE__ */ jsx52(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs28(Button, { ref, variant: "ghost", size: "xs", className: cn("shrink-0", className), children: [
2659
+ /* @__PURE__ */ jsx52(Plus, { className: "size-4", "aria-hidden": true }),
2578
2660
  label
2579
2661
  ] }) }),
2580
- /* @__PURE__ */ jsx51(PopoverContent, { align: "end", className: "w-72 p-0", children: /* @__PURE__ */ jsxs27(Command, { shouldFilter: false, label: search, children: [
2581
- /* @__PURE__ */ jsx51(CommandInput, { autoFocus: true, value: q, onValueChange: setQ, placeholder: search }),
2582
- /* @__PURE__ */ jsxs27(CommandList, { className: "max-h-[18rem] p-1", children: [
2583
- /* @__PURE__ */ jsx51(CommandEmpty, { children: q ? `No ${noun} match.` : `No ${noun} left to add.` }),
2584
- matches.map((item) => /* @__PURE__ */ jsx51(
2662
+ /* @__PURE__ */ jsx52(PopoverContent, { align: "end", className: "w-72 p-0", children: /* @__PURE__ */ jsxs28(Command, { shouldFilter: false, label: search, children: [
2663
+ /* @__PURE__ */ jsx52(CommandInput, { autoFocus: true, value: q, onValueChange: setQ, placeholder: search }),
2664
+ /* @__PURE__ */ jsxs28(CommandList, { className: "max-h-[18rem] p-1", children: [
2665
+ /* @__PURE__ */ jsx52(CommandEmpty, { children: q ? `No ${noun} match.` : `No ${noun} left to add.` }),
2666
+ matches.map((item) => /* @__PURE__ */ jsx52(
2585
2667
  CommandItem,
2586
2668
  {
2587
2669
  value: item.id,
@@ -2592,7 +2674,7 @@ var AddPicker = React41.forwardRef(
2592
2674
  setOpen(false);
2593
2675
  setQ("");
2594
2676
  },
2595
- children: /* @__PURE__ */ jsx51("span", { className: "truncate", children: item.name })
2677
+ children: /* @__PURE__ */ jsx52("span", { className: "truncate", children: item.name })
2596
2678
  },
2597
2679
  item.id
2598
2680
  ))
@@ -2606,31 +2688,31 @@ var AddPicker = React41.forwardRef(
2606
2688
  AddPicker.displayName = "AddPicker";
2607
2689
 
2608
2690
  // src/components/carousel.tsx
2609
- import * as React42 from "react";
2691
+ import * as React43 from "react";
2610
2692
  import useEmblaCarousel from "embla-carousel-react";
2611
2693
  import { ArrowLeft, ArrowRight } from "lucide-react";
2612
- import { jsx as jsx52, jsxs as jsxs28 } from "react/jsx-runtime";
2613
- var CarouselContext = React42.createContext(null);
2694
+ import { jsx as jsx53, jsxs as jsxs29 } from "react/jsx-runtime";
2695
+ var CarouselContext = React43.createContext(null);
2614
2696
  function useCarousel() {
2615
- const context = React42.useContext(CarouselContext);
2697
+ const context = React43.useContext(CarouselContext);
2616
2698
  if (!context) throw new Error("useCarousel must be used within a <Carousel />");
2617
2699
  return context;
2618
2700
  }
2619
- var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }, ref) => {
2701
+ var Carousel = React43.forwardRef(({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }, ref) => {
2620
2702
  const [carouselRef, api] = useEmblaCarousel(
2621
2703
  { ...opts, axis: orientation === "horizontal" ? "x" : "y" },
2622
2704
  plugins
2623
2705
  );
2624
- const [canScrollPrev, setCanScrollPrev] = React42.useState(false);
2625
- const [canScrollNext, setCanScrollNext] = React42.useState(false);
2626
- const onSelect = React42.useCallback((emblaApi) => {
2706
+ const [canScrollPrev, setCanScrollPrev] = React43.useState(false);
2707
+ const [canScrollNext, setCanScrollNext] = React43.useState(false);
2708
+ const onSelect = React43.useCallback((emblaApi) => {
2627
2709
  if (!emblaApi) return;
2628
2710
  setCanScrollPrev(emblaApi.canScrollPrev());
2629
2711
  setCanScrollNext(emblaApi.canScrollNext());
2630
2712
  }, []);
2631
- const scrollPrev = React42.useCallback(() => api?.scrollPrev(), [api]);
2632
- const scrollNext = React42.useCallback(() => api?.scrollNext(), [api]);
2633
- const handleKeyDown = React42.useCallback(
2713
+ const scrollPrev = React43.useCallback(() => api?.scrollPrev(), [api]);
2714
+ const scrollNext = React43.useCallback(() => api?.scrollNext(), [api]);
2715
+ const handleKeyDown = React43.useCallback(
2634
2716
  (event) => {
2635
2717
  if (event.key === "ArrowLeft") {
2636
2718
  event.preventDefault();
@@ -2642,11 +2724,11 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
2642
2724
  },
2643
2725
  [scrollPrev, scrollNext]
2644
2726
  );
2645
- React42.useEffect(() => {
2727
+ React43.useEffect(() => {
2646
2728
  if (!api || !setApi) return;
2647
2729
  setApi(api);
2648
2730
  }, [api, setApi]);
2649
- React42.useEffect(() => {
2731
+ React43.useEffect(() => {
2650
2732
  if (!api) return;
2651
2733
  onSelect(api);
2652
2734
  api.on("reInit", onSelect);
@@ -2656,7 +2738,7 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
2656
2738
  api.off("select", onSelect);
2657
2739
  };
2658
2740
  }, [api, onSelect]);
2659
- return /* @__PURE__ */ jsx52(
2741
+ return /* @__PURE__ */ jsx53(
2660
2742
  CarouselContext.Provider,
2661
2743
  {
2662
2744
  value: {
@@ -2669,7 +2751,7 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
2669
2751
  canScrollPrev,
2670
2752
  canScrollNext
2671
2753
  },
2672
- children: /* @__PURE__ */ jsx52(
2754
+ children: /* @__PURE__ */ jsx53(
2673
2755
  "div",
2674
2756
  {
2675
2757
  ref,
@@ -2685,10 +2767,10 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
2685
2767
  );
2686
2768
  });
2687
2769
  Carousel.displayName = "Carousel";
2688
- var CarouselContent = React42.forwardRef(
2770
+ var CarouselContent = React43.forwardRef(
2689
2771
  ({ className, ...props }, ref) => {
2690
2772
  const { carouselRef, orientation } = useCarousel();
2691
- return /* @__PURE__ */ jsx52("div", { ref: carouselRef, className: "overflow-hidden", children: /* @__PURE__ */ jsx52(
2773
+ return /* @__PURE__ */ jsx53("div", { ref: carouselRef, className: "overflow-hidden", children: /* @__PURE__ */ jsx53(
2692
2774
  "div",
2693
2775
  {
2694
2776
  ref,
@@ -2699,10 +2781,10 @@ var CarouselContent = React42.forwardRef(
2699
2781
  }
2700
2782
  );
2701
2783
  CarouselContent.displayName = "CarouselContent";
2702
- var CarouselItem = React42.forwardRef(
2784
+ var CarouselItem = React43.forwardRef(
2703
2785
  ({ className, ...props }, ref) => {
2704
2786
  const { orientation } = useCarousel();
2705
- return /* @__PURE__ */ jsx52(
2787
+ return /* @__PURE__ */ jsx53(
2706
2788
  "div",
2707
2789
  {
2708
2790
  ref,
@@ -2719,9 +2801,9 @@ var CarouselItem = React42.forwardRef(
2719
2801
  }
2720
2802
  );
2721
2803
  CarouselItem.displayName = "CarouselItem";
2722
- var CarouselPrevious = React42.forwardRef(({ className, ...props }, ref) => {
2804
+ var CarouselPrevious = React43.forwardRef(({ className, ...props }, ref) => {
2723
2805
  const { orientation, scrollPrev, canScrollPrev } = useCarousel();
2724
- return /* @__PURE__ */ jsxs28(
2806
+ return /* @__PURE__ */ jsxs29(
2725
2807
  "button",
2726
2808
  {
2727
2809
  ref,
@@ -2736,16 +2818,16 @@ var CarouselPrevious = React42.forwardRef(({ className, ...props }, ref) => {
2736
2818
  onClick: scrollPrev,
2737
2819
  ...props,
2738
2820
  children: [
2739
- /* @__PURE__ */ jsx52(ArrowLeft, { className: "size-4" }),
2740
- /* @__PURE__ */ jsx52("span", { className: "sr-only", children: "Previous slide" })
2821
+ /* @__PURE__ */ jsx53(ArrowLeft, { className: "size-4" }),
2822
+ /* @__PURE__ */ jsx53("span", { className: "sr-only", children: "Previous slide" })
2741
2823
  ]
2742
2824
  }
2743
2825
  );
2744
2826
  });
2745
2827
  CarouselPrevious.displayName = "CarouselPrevious";
2746
- var CarouselNext = React42.forwardRef(({ className, ...props }, ref) => {
2828
+ var CarouselNext = React43.forwardRef(({ className, ...props }, ref) => {
2747
2829
  const { orientation, scrollNext, canScrollNext } = useCarousel();
2748
- return /* @__PURE__ */ jsxs28(
2830
+ return /* @__PURE__ */ jsxs29(
2749
2831
  "button",
2750
2832
  {
2751
2833
  ref,
@@ -2760,8 +2842,8 @@ var CarouselNext = React42.forwardRef(({ className, ...props }, ref) => {
2760
2842
  onClick: scrollNext,
2761
2843
  ...props,
2762
2844
  children: [
2763
- /* @__PURE__ */ jsx52(ArrowRight, { className: "size-4" }),
2764
- /* @__PURE__ */ jsx52("span", { className: "sr-only", children: "Next slide" })
2845
+ /* @__PURE__ */ jsx53(ArrowRight, { className: "size-4" }),
2846
+ /* @__PURE__ */ jsx53("span", { className: "sr-only", children: "Next slide" })
2765
2847
  ]
2766
2848
  }
2767
2849
  );
@@ -2769,7 +2851,7 @@ var CarouselNext = React42.forwardRef(({ className, ...props }, ref) => {
2769
2851
  CarouselNext.displayName = "CarouselNext";
2770
2852
 
2771
2853
  // src/components/form.tsx
2772
- import * as React43 from "react";
2854
+ import * as React44 from "react";
2773
2855
  import { Slot as Slot2 } from "@radix-ui/react-slot";
2774
2856
  import {
2775
2857
  Controller,
@@ -2777,16 +2859,16 @@ import {
2777
2859
  useFormContext,
2778
2860
  useFormState
2779
2861
  } from "react-hook-form";
2780
- import { jsx as jsx53 } from "react/jsx-runtime";
2862
+ import { jsx as jsx54 } from "react/jsx-runtime";
2781
2863
  var Form = FormProvider;
2782
- var FormFieldContext = React43.createContext(null);
2864
+ var FormFieldContext = React44.createContext(null);
2783
2865
  function FormField({ ...props }) {
2784
- return /* @__PURE__ */ jsx53(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx53(Controller, { ...props }) });
2866
+ return /* @__PURE__ */ jsx54(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx54(Controller, { ...props }) });
2785
2867
  }
2786
- var FormItemContext = React43.createContext(null);
2868
+ var FormItemContext = React44.createContext(null);
2787
2869
  function useFormField() {
2788
- const fieldContext = React43.useContext(FormFieldContext);
2789
- const itemContext = React43.useContext(FormItemContext);
2870
+ const fieldContext = React44.useContext(FormFieldContext);
2871
+ const itemContext = React44.useContext(FormItemContext);
2790
2872
  const { getFieldState } = useFormContext();
2791
2873
  const formState = useFormState({ name: fieldContext?.name });
2792
2874
  if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
@@ -2801,16 +2883,16 @@ function useFormField() {
2801
2883
  ...fieldState
2802
2884
  };
2803
2885
  }
2804
- var FormItem = React43.forwardRef(
2886
+ var FormItem = React44.forwardRef(
2805
2887
  ({ className, ...props }, ref) => {
2806
- const id = React43.useId();
2807
- return /* @__PURE__ */ jsx53(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx53("div", { ref, className: cn("space-y-2", className), ...props }) });
2888
+ const id = React44.useId();
2889
+ return /* @__PURE__ */ jsx54(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx54("div", { ref, className: cn("space-y-2", className), ...props }) });
2808
2890
  }
2809
2891
  );
2810
2892
  FormItem.displayName = "FormItem";
2811
- var FormLabel = React43.forwardRef(({ className, ...props }, ref) => {
2893
+ var FormLabel = React44.forwardRef(({ className, ...props }, ref) => {
2812
2894
  const { error, formItemId } = useFormField();
2813
- return /* @__PURE__ */ jsx53(
2895
+ return /* @__PURE__ */ jsx54(
2814
2896
  Label2,
2815
2897
  {
2816
2898
  ref,
@@ -2821,9 +2903,9 @@ var FormLabel = React43.forwardRef(({ className, ...props }, ref) => {
2821
2903
  );
2822
2904
  });
2823
2905
  FormLabel.displayName = "FormLabel";
2824
- var FormControl = React43.forwardRef(({ ...props }, ref) => {
2906
+ var FormControl = React44.forwardRef(({ ...props }, ref) => {
2825
2907
  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
2826
- return /* @__PURE__ */ jsx53(
2908
+ return /* @__PURE__ */ jsx54(
2827
2909
  Slot2,
2828
2910
  {
2829
2911
  ref,
@@ -2835,9 +2917,9 @@ var FormControl = React43.forwardRef(({ ...props }, ref) => {
2835
2917
  );
2836
2918
  });
2837
2919
  FormControl.displayName = "FormControl";
2838
- var FormDescription = React43.forwardRef(({ className, ...props }, ref) => {
2920
+ var FormDescription = React44.forwardRef(({ className, ...props }, ref) => {
2839
2921
  const { formDescriptionId } = useFormField();
2840
- return /* @__PURE__ */ jsx53(
2922
+ return /* @__PURE__ */ jsx54(
2841
2923
  "p",
2842
2924
  {
2843
2925
  ref,
@@ -2848,11 +2930,11 @@ var FormDescription = React43.forwardRef(({ className, ...props }, ref) => {
2848
2930
  );
2849
2931
  });
2850
2932
  FormDescription.displayName = "FormDescription";
2851
- var FormMessage = React43.forwardRef(({ className, children, ...props }, ref) => {
2933
+ var FormMessage = React44.forwardRef(({ className, children, ...props }, ref) => {
2852
2934
  const { error, formMessageId } = useFormField();
2853
2935
  const body = error ? String(error?.message ?? "") : children;
2854
2936
  if (!body) return null;
2855
- return /* @__PURE__ */ jsx53(
2937
+ return /* @__PURE__ */ jsx54(
2856
2938
  "p",
2857
2939
  {
2858
2940
  ref,
@@ -2866,9 +2948,9 @@ var FormMessage = React43.forwardRef(({ className, children, ...props }, ref) =>
2866
2948
  FormMessage.displayName = "FormMessage";
2867
2949
 
2868
2950
  // src/components/status-dot.tsx
2869
- import * as React44 from "react";
2951
+ import * as React45 from "react";
2870
2952
  import { cva as cva7 } from "class-variance-authority";
2871
- import { jsx as jsx54, jsxs as jsxs29 } from "react/jsx-runtime";
2953
+ import { jsx as jsx55, jsxs as jsxs30 } from "react/jsx-runtime";
2872
2954
  var statusDotVariants = cva7("inline-block shrink-0 rounded-full", {
2873
2955
  variants: {
2874
2956
  status: {
@@ -2882,8 +2964,8 @@ var statusDotVariants = cva7("inline-block shrink-0 rounded-full", {
2882
2964
  },
2883
2965
  defaultVariants: { status: "neutral", size: "md" }
2884
2966
  });
2885
- var StatusDot = React44.forwardRef(
2886
- ({ className, status, size, pulse = false, label, ...props }, ref) => /* @__PURE__ */ jsxs29(
2967
+ var StatusDot = React45.forwardRef(
2968
+ ({ className, status, size, pulse = false, label, ...props }, ref) => /* @__PURE__ */ jsxs30(
2887
2969
  "span",
2888
2970
  {
2889
2971
  ref,
@@ -2891,14 +2973,14 @@ var StatusDot = React44.forwardRef(
2891
2973
  className: cn("relative inline-flex", className),
2892
2974
  ...props,
2893
2975
  children: [
2894
- pulse && /* @__PURE__ */ jsx54(
2976
+ pulse && /* @__PURE__ */ jsx55(
2895
2977
  "span",
2896
2978
  {
2897
2979
  "aria-hidden": "true",
2898
2980
  className: cn(statusDotVariants({ status, size }), "absolute inset-0 animate-ping opacity-75")
2899
2981
  }
2900
2982
  ),
2901
- /* @__PURE__ */ jsx54("span", { className: cn(statusDotVariants({ status, size })) })
2983
+ /* @__PURE__ */ jsx55("span", { className: cn(statusDotVariants({ status, size })) })
2902
2984
  ]
2903
2985
  }
2904
2986
  )
@@ -2906,11 +2988,11 @@ var StatusDot = React44.forwardRef(
2906
2988
  StatusDot.displayName = "StatusDot";
2907
2989
 
2908
2990
  // src/components/docs-link.tsx
2909
- import * as React45 from "react";
2991
+ import * as React46 from "react";
2910
2992
  import { BookOpen, ExternalLink } from "lucide-react";
2911
- import { jsx as jsx55, jsxs as jsxs30 } from "react/jsx-runtime";
2912
- var DocsLink = React45.forwardRef(
2913
- ({ href = "https://docs.lessly.com", label = "Docs", showLeadingIcon = true, className, ...props }, ref) => /* @__PURE__ */ jsxs30(
2993
+ import { jsx as jsx56, jsxs as jsxs31 } from "react/jsx-runtime";
2994
+ var DocsLink = React46.forwardRef(
2995
+ ({ href = "https://docs.lessly.com", label = "Docs", showLeadingIcon = true, className, ...props }, ref) => /* @__PURE__ */ jsxs31(
2914
2996
  "a",
2915
2997
  {
2916
2998
  ref,
@@ -2923,9 +3005,9 @@ var DocsLink = React45.forwardRef(
2923
3005
  ),
2924
3006
  ...props,
2925
3007
  children: [
2926
- showLeadingIcon && /* @__PURE__ */ jsx55(BookOpen, { className: "size-4", "aria-hidden": "true" }),
3008
+ showLeadingIcon && /* @__PURE__ */ jsx56(BookOpen, { className: "size-4", "aria-hidden": "true" }),
2927
3009
  label,
2928
- /* @__PURE__ */ jsx55(ExternalLink, { className: "size-3 text-text-tertiary", "aria-hidden": "true" })
3010
+ /* @__PURE__ */ jsx56(ExternalLink, { className: "size-3 text-text-tertiary", "aria-hidden": "true" })
2929
3011
  ]
2930
3012
  }
2931
3013
  )
@@ -2933,28 +3015,28 @@ var DocsLink = React45.forwardRef(
2933
3015
  DocsLink.displayName = "DocsLink";
2934
3016
 
2935
3017
  // src/components/empty-state.tsx
2936
- import * as React46 from "react";
2937
- import { jsx as jsx56, jsxs as jsxs31 } from "react/jsx-runtime";
2938
- var EmptyState = React46.forwardRef(
2939
- ({ icon: Icon, title, titleAs: TitleTag = "p", description, action, className, ...props }, ref) => /* @__PURE__ */ jsxs31("div", { ref, className: cn("flex flex-col items-center px-4 py-10 text-center", className), ...props, children: [
2940
- Icon && /* @__PURE__ */ jsx56(Icon, { className: "mb-3 size-6 text-text-tertiary", "aria-hidden": "true" }),
2941
- /* @__PURE__ */ jsx56(TitleTag, { className: "text-sm text-text-secondary", children: title }),
2942
- description && /* @__PURE__ */ jsx56("p", { className: "mt-1 max-w-sm text-sm text-text-tertiary", children: description }),
2943
- action && /* @__PURE__ */ jsx56("div", { className: "mt-3", children: action })
3018
+ import * as React47 from "react";
3019
+ import { jsx as jsx57, jsxs as jsxs32 } from "react/jsx-runtime";
3020
+ var EmptyState = React47.forwardRef(
3021
+ ({ icon: Icon, title, titleAs: TitleTag = "p", description, action, className, ...props }, ref) => /* @__PURE__ */ jsxs32("div", { ref, className: cn("flex flex-col items-center px-4 py-10 text-center", className), ...props, children: [
3022
+ Icon && /* @__PURE__ */ jsx57(Icon, { className: "mb-3 size-6 text-text-tertiary", "aria-hidden": "true" }),
3023
+ /* @__PURE__ */ jsx57(TitleTag, { className: "text-sm text-text-secondary", children: title }),
3024
+ description && /* @__PURE__ */ jsx57("p", { className: "mt-1 max-w-sm text-sm text-text-tertiary", children: description }),
3025
+ action && /* @__PURE__ */ jsx57("div", { className: "mt-3", children: action })
2944
3026
  ] })
2945
3027
  );
2946
3028
  EmptyState.displayName = "EmptyState";
2947
3029
 
2948
3030
  // src/components/copy-button.tsx
2949
- import * as React47 from "react";
3031
+ import * as React48 from "react";
2950
3032
  import { Check as Check7, Copy } from "lucide-react";
2951
- import { jsx as jsx57, jsxs as jsxs32 } from "react/jsx-runtime";
3033
+ import { jsx as jsx58, jsxs as jsxs33 } from "react/jsx-runtime";
2952
3034
  var MASK = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
2953
- var CopyButton = React47.forwardRef(
3035
+ var CopyButton = React48.forwardRef(
2954
3036
  ({ value, label = "Copy", masked = false, className, variant = "ghost", size = "icon", onClick, ...props }, ref) => {
2955
- const [copied, setCopied] = React47.useState(false);
2956
- const timer = React47.useRef(void 0);
2957
- React47.useEffect(() => () => clearTimeout(timer.current), []);
3037
+ const [copied, setCopied] = React48.useState(false);
3038
+ const timer = React48.useRef(void 0);
3039
+ React48.useEffect(() => () => clearTimeout(timer.current), []);
2958
3040
  const handleClick = async (e) => {
2959
3041
  onClick?.(e);
2960
3042
  if (!navigator.clipboard?.writeText) return;
@@ -2972,7 +3054,7 @@ var CopyButton = React47.forwardRef(
2972
3054
  // itself at the height `size` already declares instead of taking a label's padding. At the
2973
3055
  // default `size="icon"` that is the same 40px square it always was; at `xs`/`sm` it is now
2974
3056
  // square rather than a wide pill (#432).
2975
- /* @__PURE__ */ jsx57(
3057
+ /* @__PURE__ */ jsx58(
2976
3058
  Button,
2977
3059
  {
2978
3060
  ref,
@@ -2983,13 +3065,13 @@ var CopyButton = React47.forwardRef(
2983
3065
  className: cn(className),
2984
3066
  ...props,
2985
3067
  "aria-label": copied ? "Copied" : masked ? `${label} ending ${tail}` : label,
2986
- icon: copied ? /* @__PURE__ */ jsx57(Check7, { className: "text-text-success" }) : /* @__PURE__ */ jsx57(Copy, {})
3068
+ icon: copied ? /* @__PURE__ */ jsx58(Check7, { className: "text-text-success" }) : /* @__PURE__ */ jsx58(Copy, {})
2987
3069
  }
2988
3070
  )
2989
3071
  );
2990
3072
  if (!masked) return button;
2991
- return /* @__PURE__ */ jsxs32("span", { className: "inline-flex items-center gap-1.5", children: [
2992
- /* @__PURE__ */ jsx57("code", { "aria-hidden": true, className: "font-mono text-xs text-text-tertiary", children: `${MASK}${tail}` }),
3073
+ return /* @__PURE__ */ jsxs33("span", { className: "inline-flex items-center gap-1.5", children: [
3074
+ /* @__PURE__ */ jsx58("code", { "aria-hidden": true, className: "font-mono text-xs text-text-tertiary", children: `${MASK}${tail}` }),
2993
3075
  button
2994
3076
  ] });
2995
3077
  }
@@ -2997,9 +3079,9 @@ var CopyButton = React47.forwardRef(
2997
3079
  CopyButton.displayName = "CopyButton";
2998
3080
 
2999
3081
  // src/components/stat-card.tsx
3000
- import * as React48 from "react";
3082
+ import * as React49 from "react";
3001
3083
  import { ArrowDown, ArrowUp, Info as Info2, Minus as Minus2 } from "lucide-react";
3002
- import { jsx as jsx58, jsxs as jsxs33 } from "react/jsx-runtime";
3084
+ import { jsx as jsx59, jsxs as jsxs34 } from "react/jsx-runtime";
3003
3085
  var directionIcons = {
3004
3086
  up: ArrowUp,
3005
3087
  down: ArrowDown,
@@ -3015,37 +3097,39 @@ var toneFromDirection = {
3015
3097
  down: "negative",
3016
3098
  neutral: "neutral"
3017
3099
  };
3018
- var StatCard = React48.forwardRef(
3019
- ({ label, value, delta, hint, sub, icon: Icon, className, ...props }, ref) => {
3100
+ var StatCard = React49.forwardRef(
3101
+ ({ label, value, delta, hint, sub, icon: Icon, trend, className, ...props }, ref) => {
3020
3102
  const direction = delta?.direction ?? "neutral";
3021
3103
  const tone = delta?.tone ?? toneFromDirection[direction];
3022
3104
  const DeltaIcon = directionIcons[direction];
3023
3105
  const deltaClass = toneClasses[tone];
3024
- return /* @__PURE__ */ jsxs33(
3106
+ return /* @__PURE__ */ jsxs34(
3025
3107
  "div",
3026
3108
  {
3027
3109
  ref,
3028
- className: cn("rounded-xl border border-border-subtle bg-bg-surface p-5", className),
3110
+ "data-slot": "stat-card",
3111
+ className: cn("rounded-xl border border-border-subtle bg-bg-overlay p-5", className),
3029
3112
  ...props,
3030
3113
  children: [
3031
- /* @__PURE__ */ jsxs33("div", { className: "flex items-center justify-between gap-2", children: [
3032
- /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-1.5", children: [
3033
- /* @__PURE__ */ jsx58("span", { className: "text-xs font-medium text-text-tertiary", children: label }),
3034
- hint && /* @__PURE__ */ jsx58(TooltipProvider, { children: /* @__PURE__ */ jsxs33(Tooltip, { children: [
3035
- /* @__PURE__ */ jsx58(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx58("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__ */ jsx58(Info2, { className: "size-3.5", "aria-hidden": "true" }) }) }),
3036
- /* @__PURE__ */ jsx58(TooltipContent, { children: hint })
3114
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between gap-2", children: [
3115
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-1.5", children: [
3116
+ /* @__PURE__ */ jsx59("span", { className: "text-xs font-medium text-text-tertiary", children: label }),
3117
+ hint && /* @__PURE__ */ jsx59(TooltipProvider, { children: /* @__PURE__ */ jsxs34(Tooltip, { children: [
3118
+ /* @__PURE__ */ jsx59(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx59("button", { type: "button", "aria-label": "More info", className: "inline-flex cursor-pointer text-icon-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus rounded-sm", children: /* @__PURE__ */ jsx59(Info2, { className: "size-3.5", "aria-hidden": "true" }) }) }),
3119
+ /* @__PURE__ */ jsx59(TooltipContent, { children: hint })
3037
3120
  ] }) })
3038
3121
  ] }),
3039
- Icon && /* @__PURE__ */ jsx58(Icon, { className: "size-4 text-icon-secondary", "aria-hidden": "true" })
3122
+ Icon && /* @__PURE__ */ jsx59(Icon, { className: "size-4 text-icon-secondary", "aria-hidden": "true" })
3040
3123
  ] }),
3041
- /* @__PURE__ */ jsx58("div", { className: "mt-2 text-3xl font-semibold text-text-primary", children: value }),
3042
- (delta || sub) && /* @__PURE__ */ jsxs33("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [
3043
- delta && /* @__PURE__ */ jsxs33("span", { className: cn("inline-flex items-center gap-0.5 font-medium", deltaClass), children: [
3044
- /* @__PURE__ */ jsx58(DeltaIcon, { className: "size-3.5", "aria-hidden": "true" }),
3124
+ /* @__PURE__ */ jsx59("div", { className: "mt-2 text-3xl font-semibold text-text-primary", children: value }),
3125
+ (delta || sub) && /* @__PURE__ */ jsxs34("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [
3126
+ delta && /* @__PURE__ */ jsxs34("span", { className: cn("inline-flex items-center gap-0.5 font-medium", deltaClass), children: [
3127
+ /* @__PURE__ */ jsx59(DeltaIcon, { className: "size-3.5", "aria-hidden": "true" }),
3045
3128
  delta.value
3046
3129
  ] }),
3047
- sub && /* @__PURE__ */ jsx58("span", { className: "text-text-tertiary", children: sub })
3048
- ] })
3130
+ sub && /* @__PURE__ */ jsx59("span", { className: "text-text-tertiary", children: sub })
3131
+ ] }),
3132
+ trend !== void 0 && /* @__PURE__ */ jsx59("div", { "data-slot": "stat-card-trend", className: "mt-3 min-h-10", children: trend })
3049
3133
  ]
3050
3134
  }
3051
3135
  );
@@ -3054,17 +3138,17 @@ var StatCard = React48.forwardRef(
3054
3138
  StatCard.displayName = "StatCard";
3055
3139
 
3056
3140
  // src/components/confirm-dialog.tsx
3057
- import * as React50 from "react";
3141
+ import * as React51 from "react";
3058
3142
  import { Loader2 as Loader22 } from "lucide-react";
3059
3143
 
3060
3144
  // src/components/step-up-challenge.tsx
3061
- import * as React49 from "react";
3145
+ import * as React50 from "react";
3062
3146
  import { Fingerprint, Loader2 } from "lucide-react";
3063
- import { jsx as jsx59, jsxs as jsxs34 } from "react/jsx-runtime";
3147
+ import { jsx as jsx60, jsxs as jsxs35 } from "react/jsx-runtime";
3064
3148
  var DEFAULT_METHODS = ["passkey", "code"];
3065
3149
  var ATTEMPT_GAP_MS = 500;
3066
- var FACTOR_SWITCH = "w-fit rounded-sm text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50";
3067
- var StepUpChallenge = React49.forwardRef((props, ref) => {
3150
+ var FACTOR_SWITCH = "w-fit cursor-pointer rounded-sm text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50";
3151
+ var StepUpChallenge = React50.forwardRef((props, ref) => {
3068
3152
  const {
3069
3153
  methods,
3070
3154
  defaultMethod,
@@ -3084,28 +3168,28 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3084
3168
  const offered = methods && methods.length > 0 ? methods : DEFAULT_METHODS;
3085
3169
  const first = offered[0] ?? "passkey";
3086
3170
  const initial = defaultMethod && offered.includes(defaultMethod) ? defaultMethod : first;
3087
- const [method, setMethod] = React49.useState(initial);
3088
- const [code, setCode] = React49.useState("");
3089
- const [errorFactor, setErrorFactor] = React49.useState(initial);
3090
- const [attempted, setAttempted] = React49.useState(false);
3091
- const fieldRef = React49.useRef(null);
3092
- const mounted = React49.useRef(false);
3093
- const pending = React49.useRef(false);
3094
- const attemptedAt = React49.useRef(0);
3171
+ const [method, setMethod] = React50.useState(initial);
3172
+ const [code, setCode] = React50.useState("");
3173
+ const [errorFactor, setErrorFactor] = React50.useState(initial);
3174
+ const [attempted, setAttempted] = React50.useState(false);
3175
+ const fieldRef = React50.useRef(null);
3176
+ const mounted = React50.useRef(false);
3177
+ const pending = React50.useRef(false);
3178
+ const attemptedAt = React50.useRef(0);
3095
3179
  const active = offered.includes(method) ? method : first;
3096
3180
  const other = offered.find((m) => m !== active);
3097
3181
  const showError = Boolean(error) && errorFactor === active;
3098
- const reactId = React49.useId();
3182
+ const reactId = React50.useId();
3099
3183
  const fieldId = `${reactId}-code`;
3100
3184
  const errorId = `${reactId}-error`;
3101
- React49.useEffect(() => {
3185
+ React50.useEffect(() => {
3102
3186
  pending.current = false;
3103
3187
  }, [verifying, error]);
3104
- React49.useEffect(() => {
3188
+ React50.useEffect(() => {
3105
3189
  if (!error) return;
3106
3190
  fieldRef.current?.focus();
3107
3191
  }, [error]);
3108
- React49.useEffect(() => {
3192
+ React50.useEffect(() => {
3109
3193
  if (!mounted.current) {
3110
3194
  mounted.current = true;
3111
3195
  return;
@@ -3140,7 +3224,7 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3140
3224
  const stopCodeBearingEvent = (event) => {
3141
3225
  event.stopPropagation();
3142
3226
  };
3143
- return /* @__PURE__ */ jsxs34(
3227
+ return /* @__PURE__ */ jsxs35(
3144
3228
  "div",
3145
3229
  {
3146
3230
  ...rest,
@@ -3148,15 +3232,15 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3148
3232
  "aria-busy": verifying || void 0,
3149
3233
  className: cn("grid gap-4", className),
3150
3234
  children: [
3151
- active === "passkey" ? /* @__PURE__ */ jsxs34("div", { className: "grid justify-items-start gap-2", children: [
3152
- /* @__PURE__ */ jsx59(Fingerprint, { className: "size-5 text-text-secondary", "aria-hidden": "true" }),
3153
- /* @__PURE__ */ jsx59("p", { className: "text-sm text-text-secondary", children: "Your device will ask for your fingerprint, face or PIN." }),
3235
+ active === "passkey" ? /* @__PURE__ */ jsxs35("div", { className: "grid justify-items-start gap-2", children: [
3236
+ /* @__PURE__ */ jsx60(Fingerprint, { className: "size-5 text-text-secondary", "aria-hidden": "true" }),
3237
+ /* @__PURE__ */ jsx60("p", { className: "text-sm text-text-secondary", children: "Your device will ask for your fingerprint, face or PIN." }),
3154
3238
  other === "code" && // Not a `Button` (Guidelines/When it isn't a Button): a `Button` here would read as a
3155
3239
  // second action competing with the confirm below.
3156
- /* @__PURE__ */ jsx59("button", { type: "button", className: FACTOR_SWITCH, disabled: verifying, onClick: () => switchTo("code"), children: `Use a ${codeLength}-digit code instead` })
3157
- ] }) : /* @__PURE__ */ jsxs34("div", { className: "grid justify-items-start gap-2", children: [
3158
- /* @__PURE__ */ jsx59("label", { htmlFor: fieldId, className: "text-sm font-medium text-text-primary", children: `${codeLength}-digit code` }),
3159
- /* @__PURE__ */ jsx59(
3240
+ /* @__PURE__ */ jsx60("button", { type: "button", className: FACTOR_SWITCH, disabled: verifying, onClick: () => switchTo("code"), children: `Use a ${codeLength}-digit code instead` })
3241
+ ] }) : /* @__PURE__ */ jsxs35("div", { className: "grid justify-items-start gap-2", children: [
3242
+ /* @__PURE__ */ jsx60("label", { htmlFor: fieldId, className: "text-sm font-medium text-text-primary", children: `${codeLength}-digit code` }),
3243
+ /* @__PURE__ */ jsx60(
3160
3244
  "div",
3161
3245
  {
3162
3246
  "data-sensitive": "one-time-code",
@@ -3169,7 +3253,7 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3169
3253
  onDrop: stopCodeBearingEvent,
3170
3254
  onKeyDown: stopCodeBearingKey,
3171
3255
  onKeyUp: stopCodeBearingKey,
3172
- children: /* @__PURE__ */ jsx59(
3256
+ children: /* @__PURE__ */ jsx60(
3173
3257
  InputOTP,
3174
3258
  {
3175
3259
  ref: fieldRef,
@@ -3190,18 +3274,18 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3190
3274
  event.preventDefault();
3191
3275
  submit();
3192
3276
  },
3193
- children: /* @__PURE__ */ jsx59(InputOTPGroup, { children: Array.from({ length: codeLength }, (_, index) => /* @__PURE__ */ jsx59(InputOTPSlot, { index }, index)) })
3277
+ children: /* @__PURE__ */ jsx60(InputOTPGroup, { children: Array.from({ length: codeLength }, (_, index) => /* @__PURE__ */ jsx60(InputOTPSlot, { index }, index)) })
3194
3278
  }
3195
3279
  )
3196
3280
  }
3197
3281
  ),
3198
3282
  other === "passkey" && // The mirror of the line in the passkey pane — see the note there.
3199
- /* @__PURE__ */ jsx59("button", { type: "button", className: FACTOR_SWITCH, disabled: verifying, onClick: () => switchTo("passkey"), children: "Use a passkey instead" })
3283
+ /* @__PURE__ */ jsx60("button", { type: "button", className: FACTOR_SWITCH, disabled: verifying, onClick: () => switchTo("passkey"), children: "Use a passkey instead" })
3200
3284
  ] }),
3201
- showError && /* @__PURE__ */ jsx59(InlineError, { id: errorId, children: error }),
3202
- /* @__PURE__ */ jsxs34(DialogFooter, { children: [
3203
- onBack && /* @__PURE__ */ jsx59(Button, { type: "button", variant: "outline", size: "sm", disabled: verifying, onClick: onBack, children: backLabel }),
3204
- /* @__PURE__ */ jsx59(
3285
+ showError && /* @__PURE__ */ jsx60(InlineError, { id: errorId, children: error }),
3286
+ /* @__PURE__ */ jsxs35(DialogFooter, { children: [
3287
+ onBack && /* @__PURE__ */ jsx60(Button, { type: "button", variant: "outline", size: "sm", disabled: verifying, onClick: onBack, children: backLabel }),
3288
+ /* @__PURE__ */ jsx60(
3205
3289
  Button,
3206
3290
  {
3207
3291
  type: "button",
@@ -3211,7 +3295,7 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3211
3295
  "aria-disabled": !canSubmit || void 0,
3212
3296
  "aria-busy": verifying || void 0,
3213
3297
  className: cn(!canSubmit && "opacity-50"),
3214
- icon: verifying ? /* @__PURE__ */ jsx59(Loader2, { className: "animate-spin" }) : void 0,
3298
+ icon: verifying ? /* @__PURE__ */ jsx60(Loader2, { className: "animate-spin" }) : void 0,
3215
3299
  onClick: submit,
3216
3300
  children: confirmLabel
3217
3301
  }
@@ -3224,9 +3308,9 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
3224
3308
  StepUpChallenge.displayName = "StepUpChallenge";
3225
3309
 
3226
3310
  // src/components/confirm-dialog.tsx
3227
- import { jsx as jsx60, jsxs as jsxs35 } from "react/jsx-runtime";
3228
- var InlineError = React50.forwardRef(
3229
- ({ children, className, ...props }, ref) => /* @__PURE__ */ jsx60(
3311
+ import { jsx as jsx61, jsxs as jsxs36 } from "react/jsx-runtime";
3312
+ var InlineError = React51.forwardRef(
3313
+ ({ children, className, ...props }, ref) => /* @__PURE__ */ jsx61(
3230
3314
  "div",
3231
3315
  {
3232
3316
  ref,
@@ -3256,14 +3340,14 @@ function ConfirmDialog({
3256
3340
  onConfirm,
3257
3341
  onError
3258
3342
  }) {
3259
- const [internalOpen, setInternalOpen] = React50.useState(false);
3343
+ const [internalOpen, setInternalOpen] = React51.useState(false);
3260
3344
  const isControlled = open !== void 0;
3261
3345
  const actualOpen = isControlled ? open : internalOpen;
3262
- const [busy, setBusy] = React50.useState(false);
3263
- const [error, setError] = React50.useState(null);
3264
- const [typed, setTyped] = React50.useState("");
3265
- const [stepped, setStepped] = React50.useState(false);
3266
- const phraseId = `${React50.useId()}-phrase`;
3346
+ const [busy, setBusy] = React51.useState(false);
3347
+ const [error, setError] = React51.useState(null);
3348
+ const [typed, setTyped] = React51.useState("");
3349
+ const [stepped, setStepped] = React51.useState(false);
3350
+ const phraseId = `${React51.useId()}-phrase`;
3267
3351
  const phraseMet = !confirmPhrase || typed.trim().toLowerCase() === confirmPhrase.trim().toLowerCase();
3268
3352
  const challenging = Boolean(stepUp) && (!confirmPhrase || stepped);
3269
3353
  const panelTitle = challenging ? stepUp?.title ?? title : title;
@@ -3273,7 +3357,7 @@ function ConfirmDialog({
3273
3357
  setTyped("");
3274
3358
  setStepped(false);
3275
3359
  };
3276
- React50.useEffect(() => {
3360
+ React51.useEffect(() => {
3277
3361
  if (!actualOpen) reset();
3278
3362
  }, [actualOpen]);
3279
3363
  const setOpen = (next) => {
@@ -3293,22 +3377,22 @@ function ConfirmDialog({
3293
3377
  setBusy(false);
3294
3378
  }
3295
3379
  };
3296
- return /* @__PURE__ */ jsxs35(Dialog, { open: actualOpen, onOpenChange: (next) => {
3380
+ return /* @__PURE__ */ jsxs36(Dialog, { open: actualOpen, onOpenChange: (next) => {
3297
3381
  if (!busy) setOpen(next);
3298
3382
  }, children: [
3299
- trigger && /* @__PURE__ */ jsx60(DialogTrigger, { asChild: true, children: trigger }),
3300
- /* @__PURE__ */ jsxs35(DialogContent, { children: [
3301
- /* @__PURE__ */ jsxs35(DialogHeader, { children: [
3302
- /* @__PURE__ */ jsx60(DialogTitle, { children: panelTitle }),
3303
- panelDescription && /* @__PURE__ */ jsx60(DialogDescription, { children: panelDescription })
3383
+ trigger && /* @__PURE__ */ jsx61(DialogTrigger, { asChild: true, children: trigger }),
3384
+ /* @__PURE__ */ jsxs36(DialogContent, { children: [
3385
+ /* @__PURE__ */ jsxs36(DialogHeader, { children: [
3386
+ /* @__PURE__ */ jsx61(DialogTitle, { children: panelTitle }),
3387
+ panelDescription && /* @__PURE__ */ jsx61(DialogDescription, { children: panelDescription })
3304
3388
  ] }),
3305
- confirmPhrase && !challenging && /* @__PURE__ */ jsxs35("div", { className: "grid gap-1.5", children: [
3306
- /* @__PURE__ */ jsxs35("label", { htmlFor: phraseId, className: "text-xs font-medium text-text-secondary", children: [
3389
+ confirmPhrase && !challenging && /* @__PURE__ */ jsxs36("div", { className: "grid gap-1.5", children: [
3390
+ /* @__PURE__ */ jsxs36("label", { htmlFor: phraseId, className: "text-xs font-medium text-text-secondary", children: [
3307
3391
  "Type ",
3308
- /* @__PURE__ */ jsx60("span", { className: "font-mono text-text-primary", children: confirmPhrase }),
3392
+ /* @__PURE__ */ jsx61("span", { className: "font-mono text-text-primary", children: confirmPhrase }),
3309
3393
  " to confirm"
3310
3394
  ] }),
3311
- /* @__PURE__ */ jsx60(
3395
+ /* @__PURE__ */ jsx61(
3312
3396
  Input,
3313
3397
  {
3314
3398
  id: phraseId,
@@ -3319,8 +3403,8 @@ function ConfirmDialog({
3319
3403
  }
3320
3404
  )
3321
3405
  ] }),
3322
- error && !challenging && /* @__PURE__ */ jsx60(InlineError, { children: error }),
3323
- challenging ? /* @__PURE__ */ jsx60(
3406
+ error && !challenging && /* @__PURE__ */ jsx61(InlineError, { children: error }),
3407
+ challenging ? /* @__PURE__ */ jsx61(
3324
3408
  StepUpChallenge,
3325
3409
  {
3326
3410
  methods: stepUp?.methods,
@@ -3339,16 +3423,16 @@ function ConfirmDialog({
3339
3423
  onVerifyPasskey: () => void handleConfirm({ method: "passkey" }),
3340
3424
  onVerifyCode: (code) => void handleConfirm({ method: "code", code })
3341
3425
  }
3342
- ) : /* @__PURE__ */ jsxs35(DialogFooter, { children: [
3343
- /* @__PURE__ */ jsx60(Button, { variant: "outline", disabled: busy, onClick: () => setOpen(false), children: cancelLabel }),
3344
- /* @__PURE__ */ jsxs35(
3426
+ ) : /* @__PURE__ */ jsxs36(DialogFooter, { children: [
3427
+ /* @__PURE__ */ jsx61(Button, { variant: "outline", disabled: busy, onClick: () => setOpen(false), children: cancelLabel }),
3428
+ /* @__PURE__ */ jsxs36(
3345
3429
  Button,
3346
3430
  {
3347
3431
  variant: destructive ? "destructive-solid" : "default",
3348
3432
  disabled: busy || !phraseMet,
3349
3433
  onClick: () => stepUp ? setStepped(true) : void handleConfirm(),
3350
3434
  children: [
3351
- busy && /* @__PURE__ */ jsx60(Loader22, { className: "size-4 animate-spin", "aria-hidden": "true" }),
3435
+ busy && /* @__PURE__ */ jsx61(Loader22, { className: "size-4 animate-spin", "aria-hidden": "true" }),
3352
3436
  confirmLabel
3353
3437
  ]
3354
3438
  }
@@ -3359,59 +3443,81 @@ function ConfirmDialog({
3359
3443
  }
3360
3444
 
3361
3445
  // src/components/user-menu.tsx
3446
+ import * as React52 from "react";
3362
3447
  import { ChevronsUpDown } from "lucide-react";
3363
- import { Fragment as Fragment2, jsx as jsx61, jsxs as jsxs36 } from "react/jsx-runtime";
3364
- function UserMenu({ user, items, collapsed = false, align = "start" }) {
3448
+ import { Fragment as Fragment3, jsx as jsx62, jsxs as jsxs37 } from "react/jsx-runtime";
3449
+ function UserMenu({ user, items, collapsed = false, tooltip = true, align = "start" }) {
3450
+ const openedByPointer = React52.useRef(false);
3365
3451
  const secondLine = user.subtitle ?? user.email;
3366
- const avatar = /* @__PURE__ */ jsx61(PersonAvatar, { name: user.name, id: user.id, src: user.avatarUrl, size: "sm" });
3367
- const trigger = collapsed ? /* @__PURE__ */ jsx61(
3368
- "button",
3369
- {
3370
- type: "button",
3371
- "aria-label": user.name,
3372
- className: "rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
3373
- children: avatar
3374
- }
3375
- ) : /* @__PURE__ */ jsxs36(
3452
+ const avatar = /* @__PURE__ */ jsx62(PersonAvatar, { name: user.name, id: user.id, src: user.avatarUrl, size: "sm" });
3453
+ const trigger = collapsed ? (
3454
+ // The plate every other mark in a top bar gets, drawn outside the avatar instead of behind it:
3455
+ // a round mark fills its own box, so a background under one is a background nobody sees, and
3456
+ // this trigger rested with no hover at all beside four icon buttons that all had one.
3457
+ /* @__PURE__ */ jsx62(
3458
+ "button",
3459
+ {
3460
+ type: "button",
3461
+ "aria-label": user.name,
3462
+ className: "cursor-pointer rounded-full ring-0 ring-bg-secondary transition-[box-shadow] duration-fast hover:ring-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
3463
+ children: avatar
3464
+ }
3465
+ )
3466
+ ) : /* @__PURE__ */ jsxs37(
3376
3467
  "button",
3377
3468
  {
3378
3469
  type: "button",
3379
- className: "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-[5px] text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
3470
+ className: "flex w-full cursor-pointer items-center gap-2.5 rounded-xl px-1.5 py-[5px] text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
3380
3471
  children: [
3381
3472
  avatar,
3382
- /* @__PURE__ */ jsxs36("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
3383
- /* @__PURE__ */ jsx61("span", { className: "truncate text-sm leading-[normal] font-medium text-text-primary", children: user.name }),
3384
- secondLine && /* @__PURE__ */ jsx61("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: secondLine })
3473
+ /* @__PURE__ */ jsxs37("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
3474
+ /* @__PURE__ */ jsx62("span", { className: "truncate text-sm leading-[normal] font-medium text-text-primary", children: user.name }),
3475
+ secondLine && /* @__PURE__ */ jsx62("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: secondLine })
3385
3476
  ] }),
3386
- /* @__PURE__ */ jsx61(ChevronsUpDown, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
3477
+ /* @__PURE__ */ jsx62(ChevronsUpDown, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
3387
3478
  ]
3388
3479
  }
3389
3480
  );
3390
- const menuTrigger = /* @__PURE__ */ jsx61(DropdownMenuTrigger, { asChild: true, children: trigger });
3391
- const menu = /* @__PURE__ */ jsxs36(DropdownMenu, { children: [
3392
- collapsed ? /* @__PURE__ */ jsx61(TooltipProvider, { children: /* @__PURE__ */ jsxs36(Tooltip, { children: [
3393
- /* @__PURE__ */ jsx61(TooltipTrigger, { asChild: true, children: menuTrigger }),
3394
- /* @__PURE__ */ jsx61(TooltipContent, { side: "right", children: user.name })
3481
+ const menuTrigger = /* @__PURE__ */ jsx62(
3482
+ DropdownMenuTrigger,
3483
+ {
3484
+ asChild: true,
3485
+ onPointerDown: () => {
3486
+ openedByPointer.current = true;
3487
+ },
3488
+ onKeyDown: () => {
3489
+ openedByPointer.current = false;
3490
+ },
3491
+ children: trigger
3492
+ }
3493
+ );
3494
+ const menu = /* @__PURE__ */ jsxs37(DropdownMenu, { children: [
3495
+ collapsed && tooltip ? /* @__PURE__ */ jsx62(TooltipProvider, { children: /* @__PURE__ */ jsxs37(Tooltip, { children: [
3496
+ /* @__PURE__ */ jsx62(TooltipTrigger, { asChild: true, children: menuTrigger }),
3497
+ /* @__PURE__ */ jsx62(TooltipContent, { side: "right", children: user.name })
3395
3498
  ] }) }) : menuTrigger,
3396
- /* @__PURE__ */ jsxs36(
3499
+ /* @__PURE__ */ jsxs37(
3397
3500
  DropdownMenuContent,
3398
3501
  {
3399
3502
  align,
3400
3503
  sideOffset: 6,
3504
+ onCloseAutoFocus: (e) => {
3505
+ if (openedByPointer.current) e.preventDefault();
3506
+ },
3401
3507
  className: "flex w-[var(--radix-dropdown-menu-trigger-width)] min-w-56 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
3402
3508
  children: [
3403
- /* @__PURE__ */ jsxs36(DropdownMenuLabel, { className: "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary", children: [
3404
- /* @__PURE__ */ jsx61("span", { className: "block truncate text-sm font-medium text-text-primary", children: user.name }),
3405
- collapsed && secondLine && /* @__PURE__ */ jsx61("span", { className: "block truncate text-xs font-regular text-text-tertiary", children: secondLine })
3509
+ /* @__PURE__ */ jsxs37(DropdownMenuLabel, { className: "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary", children: [
3510
+ /* @__PURE__ */ jsx62("span", { className: "block truncate text-sm font-medium text-text-primary", children: user.name }),
3511
+ collapsed && secondLine && /* @__PURE__ */ jsx62("span", { className: "block truncate text-xs font-regular text-text-tertiary", children: secondLine })
3406
3512
  ] }),
3407
- /* @__PURE__ */ jsx61(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
3513
+ /* @__PURE__ */ jsx62(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
3408
3514
  items.map((item, i) => {
3409
3515
  const Icon = item.icon;
3410
- const content = /* @__PURE__ */ jsxs36(Fragment2, { children: [
3411
- Icon && /* @__PURE__ */ jsx61(Icon, { className: "size-4", "aria-hidden": "true" }),
3516
+ const content = /* @__PURE__ */ jsxs37(Fragment3, { children: [
3517
+ Icon && /* @__PURE__ */ jsx62(Icon, { className: "size-4", "aria-hidden": "true" }),
3412
3518
  item.label
3413
3519
  ] });
3414
- return /* @__PURE__ */ jsx61(
3520
+ return /* @__PURE__ */ jsx62(
3415
3521
  DropdownMenuItem,
3416
3522
  {
3417
3523
  onSelect: item.onSelect,
@@ -3420,7 +3526,7 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
3420
3526
  item.destructive && "text-text-danger focus:text-text-danger"
3421
3527
  ),
3422
3528
  asChild: Boolean(item.href),
3423
- children: item.href ? /* @__PURE__ */ jsx61("a", { href: item.href, children: content }) : content
3529
+ children: item.href ? /* @__PURE__ */ jsx62("a", { href: item.href, children: content }) : content
3424
3530
  },
3425
3531
  `${item.label}-${i}`
3426
3532
  );
@@ -3433,10 +3539,10 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
3433
3539
  }
3434
3540
 
3435
3541
  // src/components/extension-icon.tsx
3436
- import * as React51 from "react";
3542
+ import * as React53 from "react";
3437
3543
  import * as LucideIcons from "lucide-react";
3438
3544
  import { Puzzle } from "lucide-react";
3439
- import { jsx as jsx62 } from "react/jsx-runtime";
3545
+ import { jsx as jsx63 } from "react/jsx-runtime";
3440
3546
  var FORWARD_REF = /* @__PURE__ */ Symbol.for("react.forward_ref");
3441
3547
  var catalog = LucideIcons;
3442
3548
  function toPascalCase(name) {
@@ -3461,22 +3567,22 @@ function warnUnknownIconOnce(name) {
3461
3567
  warnedUnknownIcons.add(name);
3462
3568
  console.warn(`[@lessly/ui] ExtensionIcon: unknown icon "${name}" \u2014 falling back to Puzzle.`);
3463
3569
  }
3464
- var ExtensionIcon = React51.forwardRef(
3570
+ var ExtensionIcon = React53.forwardRef(
3465
3571
  ({ name, ...props }, ref) => {
3466
3572
  const Icon = resolveIcon(name);
3467
3573
  if (!Icon) {
3468
3574
  warnUnknownIconOnce(name);
3469
- return /* @__PURE__ */ jsx62(Puzzle, { ref, ...props, "data-icon-fallback": name });
3575
+ return /* @__PURE__ */ jsx63(Puzzle, { ref, ...props, "data-icon-fallback": name });
3470
3576
  }
3471
- return /* @__PURE__ */ jsx62(Icon, { ref, ...props });
3577
+ return /* @__PURE__ */ jsx63(Icon, { ref, ...props });
3472
3578
  }
3473
3579
  );
3474
3580
  ExtensionIcon.displayName = "ExtensionIcon";
3475
3581
 
3476
3582
  // src/components/icon-hint.tsx
3477
- import * as React52 from "react";
3478
- import { jsx as jsx63, jsxs as jsxs37 } from "react/jsx-runtime";
3479
- var IconHint = React52.forwardRef(
3583
+ import * as React54 from "react";
3584
+ import { jsx as jsx64, jsxs as jsxs38 } from "react/jsx-runtime";
3585
+ var IconHint = React54.forwardRef(
3480
3586
  ({ children, label, side = "top", align = "center", className, ...props }, ref) => {
3481
3587
  if (label.trim().length === 0) {
3482
3588
  if (process.env.NODE_ENV !== "production") {
@@ -3484,7 +3590,7 @@ var IconHint = React52.forwardRef(
3484
3590
  '[IconHint] `label` is blank: there is no name to expose and no sentence to show, and a focusable role="img" with no name is a WCAG 4.1.2 failure. Rendering the glyph as decorative instead \u2014 pass a sentence, or use DecorativeIcon if it needs none.'
3485
3591
  );
3486
3592
  }
3487
- return /* @__PURE__ */ jsx63(
3593
+ return /* @__PURE__ */ jsx64(
3488
3594
  "span",
3489
3595
  {
3490
3596
  ref,
@@ -3498,8 +3604,8 @@ var IconHint = React52.forwardRef(
3498
3604
  }
3499
3605
  );
3500
3606
  }
3501
- return /* @__PURE__ */ jsxs37(Tooltip, { children: [
3502
- /* @__PURE__ */ jsx63(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx63(
3607
+ return /* @__PURE__ */ jsxs38(Tooltip, { children: [
3608
+ /* @__PURE__ */ jsx64(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx64(
3503
3609
  "span",
3504
3610
  {
3505
3611
  ref,
@@ -3516,16 +3622,16 @@ var IconHint = React52.forwardRef(
3516
3622
  children
3517
3623
  }
3518
3624
  ) }),
3519
- /* @__PURE__ */ jsx63(TooltipContent, { side, align, "aria-hidden": true, children: label })
3625
+ /* @__PURE__ */ jsx64(TooltipContent, { side, align, "aria-hidden": true, children: label })
3520
3626
  ] });
3521
3627
  }
3522
3628
  );
3523
3629
  IconHint.displayName = "IconHint";
3524
3630
 
3525
3631
  // src/components/decorative-icon.tsx
3526
- import * as React53 from "react";
3527
- import { jsx as jsx64, jsxs as jsxs38 } from "react/jsx-runtime";
3528
- var DecorativeIcon = React53.forwardRef(
3632
+ import * as React55 from "react";
3633
+ import { jsx as jsx65, jsxs as jsxs39 } from "react/jsx-runtime";
3634
+ var DecorativeIcon = React55.forwardRef(
3529
3635
  ({ children, label, side = "top", align = "center", className, ...props }, ref) => {
3530
3636
  if (label.trim().length === 0) {
3531
3637
  if (process.env.NODE_ENV !== "production") {
@@ -3533,7 +3639,7 @@ var DecorativeIcon = React53.forwardRef(
3533
3639
  "[DecorativeIcon] `label` is blank, so the tooltip would open on an empty bubble. Rendering the bare glyph instead \u2014 pass a sentence, or drop the wrapper if the glyph has nothing to add."
3534
3640
  );
3535
3641
  }
3536
- return /* @__PURE__ */ jsx64(
3642
+ return /* @__PURE__ */ jsx65(
3537
3643
  "span",
3538
3644
  {
3539
3645
  ref,
@@ -3547,8 +3653,8 @@ var DecorativeIcon = React53.forwardRef(
3547
3653
  }
3548
3654
  );
3549
3655
  }
3550
- return /* @__PURE__ */ jsxs38(Tooltip, { children: [
3551
- /* @__PURE__ */ jsx64(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx64(
3656
+ return /* @__PURE__ */ jsxs39(Tooltip, { children: [
3657
+ /* @__PURE__ */ jsx65(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx65(
3552
3658
  "span",
3553
3659
  {
3554
3660
  ref,
@@ -3564,15 +3670,15 @@ var DecorativeIcon = React53.forwardRef(
3564
3670
  children
3565
3671
  }
3566
3672
  ) }),
3567
- /* @__PURE__ */ jsx64(TooltipContent, { side, align, "aria-hidden": true, children: label })
3673
+ /* @__PURE__ */ jsx65(TooltipContent, { side, align, "aria-hidden": true, children: label })
3568
3674
  ] });
3569
3675
  }
3570
3676
  );
3571
3677
  DecorativeIcon.displayName = "DecorativeIcon";
3572
3678
 
3573
3679
  // src/components/image-cropper.tsx
3574
- import * as React54 from "react";
3575
- import { Fragment as Fragment3, jsx as jsx65, jsxs as jsxs39 } from "react/jsx-runtime";
3680
+ import * as React56 from "react";
3681
+ import { Fragment as Fragment4, jsx as jsx66, jsxs as jsxs40 } from "react/jsx-runtime";
3576
3682
  var FALLBACK_STAGE_W = 360;
3577
3683
  var FALLBACK_STAGE_H = 270;
3578
3684
  var STEP = 8;
@@ -3605,7 +3711,7 @@ var MASK_CLASS = {
3605
3711
  circle: "rounded-full"
3606
3712
  };
3607
3713
  var clampTo = (value, min, max) => Math.min(Math.max(value, min), max);
3608
- var ImageCropper = React54.forwardRef(
3714
+ var ImageCropper = React56.forwardRef(
3609
3715
  ({
3610
3716
  src,
3611
3717
  shape = "square",
@@ -3625,21 +3731,21 @@ var ImageCropper = React54.forwardRef(
3625
3731
  className,
3626
3732
  ...props
3627
3733
  }, ref) => {
3628
- const [nat, setNat] = React54.useState(null);
3629
- const [error, setError] = React54.useState(null);
3630
- const [focused, setFocused] = React54.useState(false);
3631
- const [stage, setStage] = React54.useState({ w: FALLBACK_STAGE_W, h: FALLBACK_STAGE_H });
3632
- const [crop, setCrop] = React54.useState({ x: 0, y: 0, size: 0 });
3633
- const imgRef = React54.useRef(null);
3634
- const stageRef = React54.useRef(null);
3635
- const framed = React54.useRef(false);
3636
- const inset = React54.useRef({ left: 0, top: 0 });
3637
- React54.useEffect(() => {
3734
+ const [nat, setNat] = React56.useState(null);
3735
+ const [error, setError] = React56.useState(null);
3736
+ const [focused, setFocused] = React56.useState(false);
3737
+ const [stage, setStage] = React56.useState({ w: FALLBACK_STAGE_W, h: FALLBACK_STAGE_H });
3738
+ const [crop, setCrop] = React56.useState({ x: 0, y: 0, size: 0 });
3739
+ const imgRef = React56.useRef(null);
3740
+ const stageRef = React56.useRef(null);
3741
+ const framed = React56.useRef(false);
3742
+ const inset = React56.useRef({ left: 0, top: 0 });
3743
+ React56.useEffect(() => {
3638
3744
  framed.current = false;
3639
3745
  setNat(null);
3640
3746
  setError(null);
3641
3747
  }, [src]);
3642
- React54.useLayoutEffect(() => {
3748
+ React56.useLayoutEffect(() => {
3643
3749
  const el = stageRef.current;
3644
3750
  if (!el) return void 0;
3645
3751
  const read = (entry) => {
@@ -3665,13 +3771,13 @@ var ImageCropper = React54.forwardRef(
3665
3771
  const drawH = nat ? nat.h * fit : stage.h;
3666
3772
  const padX = (stage.w - drawW) / 2;
3667
3773
  const padY = (stage.h - drawH) / 2;
3668
- React54.useEffect(() => {
3774
+ React56.useEffect(() => {
3669
3775
  if (!nat || framed.current) return;
3670
3776
  framed.current = true;
3671
3777
  const size = Math.min(nat.w, nat.h);
3672
3778
  setCrop({ x: (nat.w - size) / 2, y: (nat.h - size) / 2, size });
3673
3779
  }, [nat]);
3674
- const clampCrop = React54.useCallback(
3780
+ const clampCrop = React56.useCallback(
3675
3781
  (x, y, size) => {
3676
3782
  if (!nat) return { x, y, size };
3677
3783
  const max = Math.min(nat.w, nat.h);
@@ -3681,8 +3787,8 @@ var ImageCropper = React54.forwardRef(
3681
3787
  },
3682
3788
  [nat, fit, minCropSize]
3683
3789
  );
3684
- const moving = React54.useRef(null);
3685
- const resizing = React54.useRef(null);
3790
+ const moving = React56.useRef(null);
3791
+ const resizing = React56.useRef(null);
3686
3792
  const onMoveDown = (e) => {
3687
3793
  e.target.setPointerCapture(e.pointerId);
3688
3794
  moving.current = { px: e.clientX, py: e.clientY, cx: crop.x, cy: crop.y };
@@ -3799,8 +3905,8 @@ var ImageCropper = React54.forwardRef(
3799
3905
  const percent = nat ? Math.round(crop.size / Math.min(nat.w, nat.h) * 100) : 100;
3800
3906
  const fromLeft = nat ? Math.round(crop.x / nat.w * 100) : 0;
3801
3907
  const fromTop = nat ? Math.round(crop.y / nat.h * 100) : 0;
3802
- return /* @__PURE__ */ jsxs39("div", { ref, className: cn("flex flex-col gap-3", className), ...props, children: [
3803
- /* @__PURE__ */ jsxs39(
3908
+ return /* @__PURE__ */ jsxs40("div", { ref, className: cn("flex flex-col gap-3", className), ...props, children: [
3909
+ /* @__PURE__ */ jsxs40(
3804
3910
  "div",
3805
3911
  {
3806
3912
  ref: stageRef,
@@ -3809,7 +3915,7 @@ var ImageCropper = React54.forwardRef(
3809
3915
  onPointerMove,
3810
3916
  onPointerUp,
3811
3917
  children: [
3812
- /* @__PURE__ */ jsx65(
3918
+ /* @__PURE__ */ jsx66(
3813
3919
  "img",
3814
3920
  {
3815
3921
  ref: imgRef,
@@ -3822,8 +3928,8 @@ var ImageCropper = React54.forwardRef(
3822
3928
  className: "pointer-events-none absolute inset-0 size-full object-contain"
3823
3929
  }
3824
3930
  ),
3825
- !nat && !error && /* @__PURE__ */ jsx65("div", { className: "absolute inset-0 flex items-center justify-center text-sm text-text-tertiary", children: "Loading\u2026" }),
3826
- error === "load" && /* @__PURE__ */ jsx65(
3931
+ !nat && !error && /* @__PURE__ */ jsx66("div", { className: "absolute inset-0 flex items-center justify-center text-sm text-text-tertiary", children: "Loading\u2026" }),
3932
+ error === "load" && /* @__PURE__ */ jsx66(
3827
3933
  "div",
3828
3934
  {
3829
3935
  role: "alert",
@@ -3831,8 +3937,8 @@ var ImageCropper = React54.forwardRef(
3831
3937
  children: errorMessage
3832
3938
  }
3833
3939
  ),
3834
- nat && error !== "load" && /* @__PURE__ */ jsxs39(Fragment3, { children: [
3835
- /* @__PURE__ */ jsx65(
3940
+ nat && error !== "load" && /* @__PURE__ */ jsxs40(Fragment4, { children: [
3941
+ /* @__PURE__ */ jsx66(
3836
3942
  "div",
3837
3943
  {
3838
3944
  tabIndex: 0,
@@ -3854,15 +3960,15 @@ var ImageCropper = React54.forwardRef(
3854
3960
  cursor: "move",
3855
3961
  boxShadow: (focused ? FOCUS_SHADOW : "") + RING_SHADOW
3856
3962
  },
3857
- children: /* @__PURE__ */ jsxs39("div", { className: "pointer-events-none absolute inset-0 opacity-40", children: [
3858
- /* @__PURE__ */ jsx65("div", { className: "absolute left-1/3 top-0 h-full w-px bg-white/60" }),
3859
- /* @__PURE__ */ jsx65("div", { className: "absolute left-2/3 top-0 h-full w-px bg-white/60" }),
3860
- /* @__PURE__ */ jsx65("div", { className: "absolute left-0 top-1/3 h-px w-full bg-white/60" }),
3861
- /* @__PURE__ */ jsx65("div", { className: "absolute left-0 top-2/3 h-px w-full bg-white/60" })
3963
+ children: /* @__PURE__ */ jsxs40("div", { className: "pointer-events-none absolute inset-0 opacity-40", children: [
3964
+ /* @__PURE__ */ jsx66("div", { className: "absolute left-1/3 top-0 h-full w-px bg-white/60" }),
3965
+ /* @__PURE__ */ jsx66("div", { className: "absolute left-2/3 top-0 h-full w-px bg-white/60" }),
3966
+ /* @__PURE__ */ jsx66("div", { className: "absolute left-0 top-1/3 h-px w-full bg-white/60" }),
3967
+ /* @__PURE__ */ jsx66("div", { className: "absolute left-0 top-2/3 h-px w-full bg-white/60" })
3862
3968
  ] })
3863
3969
  }
3864
3970
  ),
3865
- CORNERS.map((corner) => /* @__PURE__ */ jsx65(
3971
+ CORNERS.map((corner) => /* @__PURE__ */ jsx66(
3866
3972
  "div",
3867
3973
  {
3868
3974
  "data-grip": corner,
@@ -3875,7 +3981,7 @@ var ImageCropper = React54.forwardRef(
3875
3981
  padding: BRACKET.inset
3876
3982
  },
3877
3983
  onPointerDown: onResizeDown(corner),
3878
- children: /* @__PURE__ */ jsx65(
3984
+ children: /* @__PURE__ */ jsx66(
3879
3985
  "span",
3880
3986
  {
3881
3987
  className: "block border-solid border-white",
@@ -3897,10 +4003,10 @@ var ImageCropper = React54.forwardRef(
3897
4003
  ]
3898
4004
  }
3899
4005
  ),
3900
- error === "export" ? /* @__PURE__ */ jsx65("p", { role: "alert", className: "text-xs text-text-danger", children: exportErrorMessage }) : hint != null && !error ? /* @__PURE__ */ jsx65("p", { className: "text-xs text-text-tertiary", children: hint }) : null,
3901
- /* @__PURE__ */ jsxs39("div", { className: "flex justify-end gap-2", children: [
3902
- onCancel && /* @__PURE__ */ jsx65(Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel, children: cancelLabel }),
3903
- /* @__PURE__ */ jsx65(Button, { type: "button", size: "sm", onClick: save, disabled: !nat || error != null, children: saveLabel })
4006
+ error === "export" ? /* @__PURE__ */ jsx66("p", { role: "alert", className: "text-xs text-text-danger", children: exportErrorMessage }) : hint != null && !error ? /* @__PURE__ */ jsx66("p", { className: "text-xs text-text-tertiary", children: hint }) : null,
4007
+ /* @__PURE__ */ jsxs40("div", { className: "flex justify-end gap-2", children: [
4008
+ onCancel && /* @__PURE__ */ jsx66(Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel, children: cancelLabel }),
4009
+ /* @__PURE__ */ jsx66(Button, { type: "button", size: "sm", onClick: save, disabled: !nat || error != null, children: saveLabel })
3904
4010
  ] })
3905
4011
  ] });
3906
4012
  }
@@ -3908,7 +4014,7 @@ var ImageCropper = React54.forwardRef(
3908
4014
  ImageCropper.displayName = "ImageCropper";
3909
4015
 
3910
4016
  // src/components/image-crop-dialog.tsx
3911
- import { jsx as jsx66, jsxs as jsxs40 } from "react/jsx-runtime";
4017
+ import { jsx as jsx67, jsxs as jsxs41 } from "react/jsx-runtime";
3912
4018
  function ImageCropDialog({
3913
4019
  open,
3914
4020
  onOpenChange,
@@ -3919,17 +4025,17 @@ function ImageCropDialog({
3919
4025
  onCrop,
3920
4026
  ...cropperProps
3921
4027
  }) {
3922
- return /* @__PURE__ */ jsx66(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs40(
4028
+ return /* @__PURE__ */ jsx67(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs41(
3923
4029
  DialogContent,
3924
4030
  {
3925
4031
  className: "sm:max-w-md",
3926
4032
  ...description ? {} : { "aria-describedby": void 0 },
3927
4033
  children: [
3928
- /* @__PURE__ */ jsxs40(DialogHeader, { children: [
3929
- /* @__PURE__ */ jsx66(DialogTitle, { children: title ?? `Crop ${label.toLowerCase()}` }),
3930
- description && /* @__PURE__ */ jsx66(DialogDescription, { children: description })
4034
+ /* @__PURE__ */ jsxs41(DialogHeader, { children: [
4035
+ /* @__PURE__ */ jsx67(DialogTitle, { children: title ?? `Crop ${label.toLowerCase()}` }),
4036
+ description && /* @__PURE__ */ jsx67(DialogDescription, { children: description })
3931
4037
  ] }),
3932
- src && /* @__PURE__ */ jsx66(
4038
+ src && /* @__PURE__ */ jsx67(
3933
4039
  ImageCropper,
3934
4040
  {
3935
4041
  src,
@@ -3948,9 +4054,9 @@ function ImageCropDialog({
3948
4054
  ImageCropDialog.displayName = "ImageCropDialog";
3949
4055
 
3950
4056
  // src/components/image-upload.tsx
3951
- import * as React55 from "react";
4057
+ import * as React57 from "react";
3952
4058
  import { Image as ImageIcon } from "lucide-react";
3953
- import { jsx as jsx67, jsxs as jsxs41 } from "react/jsx-runtime";
4059
+ import { jsx as jsx68, jsxs as jsxs42 } from "react/jsx-runtime";
3954
4060
  var PREVIEW_BOX = {
3955
4061
  sm: "size-8",
3956
4062
  md: "size-12",
@@ -3965,7 +4071,7 @@ function formatSize(bytes) {
3965
4071
  if (bytes >= 1024) return `${Math.floor(bytes / 1024)} KB`;
3966
4072
  return `${bytes} B`;
3967
4073
  }
3968
- var ImageUpload = React55.forwardRef(
4074
+ var ImageUpload = React57.forwardRef(
3969
4075
  ({
3970
4076
  value,
3971
4077
  onChange,
@@ -3988,11 +4094,11 @@ var ImageUpload = React55.forwardRef(
3988
4094
  className,
3989
4095
  ...props
3990
4096
  }, ref) => {
3991
- const inputRef = React55.useRef(null);
3992
- const [picked, setPicked] = React55.useState(null);
3993
- const [cropOpen, setCropOpen] = React55.useState(false);
3994
- const [error, setError] = React55.useState(null);
3995
- const pickSeq = React55.useRef(0);
4097
+ const inputRef = React57.useRef(null);
4098
+ const [picked, setPicked] = React57.useState(null);
4099
+ const [cropOpen, setCropOpen] = React57.useState(false);
4100
+ const [error, setError] = React57.useState(null);
4101
+ const pickSeq = React57.useRef(0);
3996
4102
  const refuse = (message) => {
3997
4103
  setError(message);
3998
4104
  onError?.(message);
@@ -4035,8 +4141,8 @@ var ImageUpload = React55.forwardRef(
4035
4141
  reader.readAsDataURL(file);
4036
4142
  };
4037
4143
  const framed = value != null || fallback == null;
4038
- return /* @__PURE__ */ jsxs41("div", { ref, className: cn("flex items-start gap-3", className), ...props, children: [
4039
- /* @__PURE__ */ jsx67(
4144
+ return /* @__PURE__ */ jsxs42("div", { ref, className: cn("flex items-start gap-3", className), ...props, children: [
4145
+ /* @__PURE__ */ jsx68(
4040
4146
  "span",
4041
4147
  {
4042
4148
  className: cn(
@@ -4045,12 +4151,12 @@ var ImageUpload = React55.forwardRef(
4045
4151
  PREVIEW_MASK[shape],
4046
4152
  framed && "border border-border-default bg-bg-secondary text-text-secondary"
4047
4153
  ),
4048
- children: value ? /* @__PURE__ */ jsx67("img", { src: value, alt: `${label} preview`, className: "size-full object-cover" }) : fallback ?? /* @__PURE__ */ jsx67(ImageIcon, { className: "size-5", "aria-hidden": true })
4154
+ children: value ? /* @__PURE__ */ jsx68("img", { src: value, alt: `${label} preview`, className: "size-full object-cover" }) : fallback ?? /* @__PURE__ */ jsx68(ImageIcon, { className: "size-5", "aria-hidden": true })
4049
4155
  }
4050
4156
  ),
4051
- /* @__PURE__ */ jsxs41("div", { className: "min-w-0 flex-1", children: [
4052
- /* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-2", children: [
4053
- /* @__PURE__ */ jsx67(
4157
+ /* @__PURE__ */ jsxs42("div", { className: "min-w-0 flex-1", children: [
4158
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2", children: [
4159
+ /* @__PURE__ */ jsx68(
4054
4160
  Button,
4055
4161
  {
4056
4162
  type: "button",
@@ -4061,7 +4167,7 @@ var ImageUpload = React55.forwardRef(
4061
4167
  children: value ? changeLabel : uploadLabel
4062
4168
  }
4063
4169
  ),
4064
- value && /* @__PURE__ */ jsx67(
4170
+ value && /* @__PURE__ */ jsx68(
4065
4171
  Button,
4066
4172
  {
4067
4173
  type: "button",
@@ -4076,10 +4182,10 @@ var ImageUpload = React55.forwardRef(
4076
4182
  }
4077
4183
  )
4078
4184
  ] }),
4079
- hint != null && /* @__PURE__ */ jsx67("p", { className: "mt-1 text-xs text-text-tertiary", children: hint }),
4080
- error && /* @__PURE__ */ jsx67("p", { role: "alert", className: "mt-1 text-xs text-text-danger", children: error })
4185
+ hint != null && /* @__PURE__ */ jsx68("p", { className: "mt-1 text-xs text-text-tertiary", children: hint }),
4186
+ error && /* @__PURE__ */ jsx68("p", { role: "alert", className: "mt-1 text-xs text-text-danger", children: error })
4081
4187
  ] }),
4082
- /* @__PURE__ */ jsx67(
4188
+ /* @__PURE__ */ jsx68(
4083
4189
  "input",
4084
4190
  {
4085
4191
  ref: inputRef,
@@ -4094,7 +4200,7 @@ var ImageUpload = React55.forwardRef(
4094
4200
  }
4095
4201
  }
4096
4202
  ),
4097
- crop && /* @__PURE__ */ jsx67(
4203
+ crop && /* @__PURE__ */ jsx68(
4098
4204
  ImageCropDialog,
4099
4205
  {
4100
4206
  open: cropOpen,
@@ -4116,75 +4222,15 @@ var ImageUpload = React55.forwardRef(
4116
4222
  );
4117
4223
  ImageUpload.displayName = "ImageUpload";
4118
4224
 
4119
- // src/components/entity-row.tsx
4120
- import * as React56 from "react";
4121
- import { Slot as Slot3 } from "@radix-ui/react-slot";
4122
- import { ChevronDown as ChevronDown5, ChevronRight as ChevronRight7 } from "lucide-react";
4123
- import { Fragment as Fragment4, jsx as jsx68, jsxs as jsxs42 } from "react/jsx-runtime";
4124
- var rowClass = "flex w-full items-center gap-3 px-4 py-2.5 text-left";
4125
- var plateClass = "relative isolate after:pointer-events-none after:absolute after:inset-x-1.5 after:inset-y-1 after:-z-10 after:rounded-lg hover:after:bg-bg-elevated disabled:hover:after:bg-transparent focus-visible:outline-none focus-visible:after:ring-2 focus-visible:after:ring-inset focus-visible:after:ring-border-focus";
4126
- var stackClass = "flex-col items-stretch gap-1";
4127
- var caretMotion = {
4128
- transitionDuration: "var(--motion-duration-normal)",
4129
- transitionTimingFunction: "var(--motion-easing-standard)"
4130
- };
4131
- var EntityRow = React56.forwardRef(function EntityRow2({ mark, title, badge, sub, meta, summary, opens = "page", expanded, asChild = false, className, children, ...props }, ref) {
4132
- if (process.env.NODE_ENV !== "production" && opens === "disclosure" && expanded === void 0) {
4133
- console.warn(
4134
- '[EntityRow] `opens="disclosure"` needs `expanded`: it draws the caret AND sets `aria-expanded`, and without it the row renders a caret that never turns and states no state at all. Pass `expanded={open}`, or use `opens="page"` / `opens="modal"`.'
4135
- );
4136
- }
4137
- const line = /* @__PURE__ */ jsxs42(Fragment4, { children: [
4138
- mark,
4139
- /* @__PURE__ */ jsxs42("span", { className: "min-w-0 flex-1", children: [
4140
- /* @__PURE__ */ jsxs42("span", { className: "flex min-h-5 items-center gap-2", children: [
4141
- /* @__PURE__ */ jsx68("span", { className: cn("truncate text-sm text-text-primary", opens !== "none" && "font-medium"), children: title }),
4142
- badge != null && /* @__PURE__ */ jsx68("span", { className: "flex h-5 shrink-0 items-center", children: badge })
4143
- ] }),
4144
- sub != null && /* @__PURE__ */ jsx68("span", { className: "block truncate text-xs text-text-secondary", children: sub })
4145
- ] }),
4146
- meta != null && /* @__PURE__ */ jsx68("span", { className: "shrink-0 text-sm text-text-secondary", children: meta }),
4147
- opens !== "none" && /* @__PURE__ */ jsxs42("span", { className: "flex size-4 shrink-0 items-center justify-center", children: [
4148
- opens === "page" && /* @__PURE__ */ jsx68(ChevronRight7, { className: "size-4 text-text-tertiary", "aria-hidden": true }),
4149
- opens === "disclosure" && /* @__PURE__ */ jsx68(
4150
- ChevronDown5,
4151
- {
4152
- className: cn(
4153
- "size-4 shrink-0 text-text-tertiary transition-transform",
4154
- expanded ? "rotate-180" : "rotate-0"
4155
- ),
4156
- style: caretMotion,
4157
- "aria-hidden": true
4158
- }
4159
- )
4160
- ] })
4161
- ] });
4162
- const content = summary == null ? line : /* @__PURE__ */ jsxs42(Fragment4, { children: [
4163
- /* @__PURE__ */ jsx68("span", { className: "flex w-full items-center gap-3", children: line }),
4164
- /* @__PURE__ */ jsx68("span", { className: "block w-full text-xs text-text-secondary", children: summary })
4165
- ] });
4166
- const classes = cn(rowClass, opens !== "none" && plateClass, summary != null && stackClass, className);
4167
- const stateProps = opens === "disclosure" ? { "aria-expanded": expanded } : void 0;
4168
- if (opens === "none") {
4169
- return /* @__PURE__ */ jsx68("div", { ...props, ref, className: classes, children: content });
4170
- }
4171
- if (asChild) {
4172
- const child = React56.Children.only(children);
4173
- return /* @__PURE__ */ jsx68(Slot3, { ...props, ref, className: classes, ...stateProps, children: React56.cloneElement(child, stateProps, content) });
4174
- }
4175
- return /* @__PURE__ */ jsx68("button", { ...props, ref, type: "button", className: classes, ...stateProps, children: content });
4176
- });
4177
- EntityRow.displayName = "EntityRow";
4178
-
4179
4225
  // src/components/back-link.tsx
4180
- import * as React57 from "react";
4226
+ import * as React58 from "react";
4181
4227
  import { ArrowLeft as ArrowLeft2 } from "lucide-react";
4182
4228
  import { Slottable } from "@radix-ui/react-slot";
4183
4229
  import { jsx as jsx69, jsxs as jsxs43 } from "react/jsx-runtime";
4184
4230
  var SLOTTED_GLYPH = "inline-flex shrink-0 items-center justify-center [&>svg]:size-3.5";
4185
- var BackLink = React57.forwardRef(
4231
+ var BackLink = React58.forwardRef(
4186
4232
  ({ parent, asChild = false, children, className, onClick, ...props }, ref) => {
4187
- const slotted = asChild && React57.isValidElement(children);
4233
+ const slotted = asChild && React58.isValidElement(children);
4188
4234
  if (!slotted && !onClick) return null;
4189
4235
  const shell = {
4190
4236
  variant: "ghost",
@@ -4204,10 +4250,10 @@ var BackLink = React57.forwardRef(
4204
4250
  BackLink.displayName = "BackLink";
4205
4251
 
4206
4252
  // src/components/card-note.tsx
4207
- import * as React58 from "react";
4208
- import { Lock } from "lucide-react";
4253
+ import * as React59 from "react";
4254
+ import { Lock as Lock2 } from "lucide-react";
4209
4255
  import { jsx as jsx70, jsxs as jsxs44 } from "react/jsx-runtime";
4210
- var CardNote = React58.forwardRef(
4256
+ var CardNote = React59.forwardRef(
4211
4257
  ({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs44(
4212
4258
  "p",
4213
4259
  {
@@ -4218,7 +4264,7 @@ var CardNote = React58.forwardRef(
4218
4264
  className
4219
4265
  ),
4220
4266
  children: [
4221
- /* @__PURE__ */ jsx70(Lock, { className: "mt-0.5 size-3 shrink-0", "aria-hidden": true }),
4267
+ /* @__PURE__ */ jsx70(Lock2, { className: "mt-0.5 size-3 shrink-0", "aria-hidden": true }),
4222
4268
  children
4223
4269
  ]
4224
4270
  }
@@ -4227,10 +4273,10 @@ var CardNote = React58.forwardRef(
4227
4273
  CardNote.displayName = "CardNote";
4228
4274
 
4229
4275
  // src/components/remove-button.tsx
4230
- import * as React59 from "react";
4276
+ import * as React60 from "react";
4231
4277
  import { X as X2 } from "lucide-react";
4232
4278
  import { jsx as jsx71, jsxs as jsxs45 } from "react/jsx-runtime";
4233
- var RemoveButton = React59.forwardRef(
4279
+ var RemoveButton = React60.forwardRef(
4234
4280
  ({ label, size = "sm", side = "top", className, ...props }, ref) => {
4235
4281
  const button = /* @__PURE__ */ jsx71(
4236
4282
  Button,
@@ -4255,7 +4301,7 @@ var RemoveButton = React59.forwardRef(
4255
4301
  RemoveButton.displayName = "RemoveButton";
4256
4302
 
4257
4303
  // src/components/grant-role-picker.tsx
4258
- import * as React60 from "react";
4304
+ import * as React61 from "react";
4259
4305
  import { Check as Check8 } from "lucide-react";
4260
4306
  import { Fragment as Fragment6, jsx as jsx72, jsxs as jsxs46 } from "react/jsx-runtime";
4261
4307
  var WEIGHT_TONE = {
@@ -4270,7 +4316,7 @@ var grantRemoveLabel = (detail, notInForce) => {
4270
4316
  if (!detail) return words;
4271
4317
  return detail.startsWith(",") ? `${words}${detail}` : `${words} ${detail}`;
4272
4318
  };
4273
- var GrantRolePicker = React60.forwardRef(
4319
+ var GrantRolePicker = React61.forwardRef(
4274
4320
  ({
4275
4321
  value,
4276
4322
  roles,
@@ -4319,7 +4365,7 @@ var GrantRolePicker = React60.forwardRef(
4319
4365
  valueNote !== void 0 && /* @__PURE__ */ jsx72("div", { className: MENU_STATEMENT, children: valueNote }),
4320
4366
  rungs && pickable.filter((r) => !r.group).map(item),
4321
4367
  rungs && // Bands in the order the roles list states them, so a caller decides the order once.
4322
- [...new Set(pickable.map((r) => r.group).filter((g) => !!g))].map((band) => /* @__PURE__ */ jsxs46(React60.Fragment, { children: [
4368
+ [...new Set(pickable.map((r) => r.group).filter((g) => !!g))].map((band) => /* @__PURE__ */ jsxs46(React61.Fragment, { children: [
4323
4369
  /* @__PURE__ */ jsx72(DropdownMenuSeparator, {}),
4324
4370
  /* @__PURE__ */ jsx72(DropdownMenuLabel, { className: "px-2 py-1 text-xs font-medium text-text-tertiary", children: band }),
4325
4371
  pickable.filter((r) => r.group === band).map(item)
@@ -4353,9 +4399,9 @@ var GrantRolePicker = React60.forwardRef(
4353
4399
  GrantRolePicker.displayName = "GrantRolePicker";
4354
4400
 
4355
4401
  // src/components/grant-row.tsx
4356
- import * as React61 from "react";
4402
+ import * as React62 from "react";
4357
4403
  import { jsx as jsx73, jsxs as jsxs47 } from "react/jsx-runtime";
4358
- var GrantRow = React61.forwardRef((props, ref) => {
4404
+ var GrantRow = React62.forwardRef((props, ref) => {
4359
4405
  const {
4360
4406
  name,
4361
4407
  role,
@@ -4449,10 +4495,10 @@ var GrantRow = React61.forwardRef((props, ref) => {
4449
4495
  GrantRow.displayName = "GrantRow";
4450
4496
 
4451
4497
  // src/components/removable-chip.tsx
4452
- import * as React62 from "react";
4498
+ import * as React63 from "react";
4453
4499
  import { X as X3 } from "lucide-react";
4454
4500
  import { jsx as jsx74, jsxs as jsxs48 } from "react/jsx-runtime";
4455
- var RemovableChip = React62.forwardRef(
4501
+ var RemovableChip = React63.forwardRef(
4456
4502
  ({ label, onRemove, leading, removeLabel, className, ...props }, ref) => /* @__PURE__ */ jsxs48(
4457
4503
  "span",
4458
4504
  {
@@ -4486,22 +4532,22 @@ var RemovableChip = React62.forwardRef(
4486
4532
  RemovableChip.displayName = "RemovableChip";
4487
4533
 
4488
4534
  // src/hooks/use-fresh-highlight.ts
4489
- import * as React63 from "react";
4535
+ import * as React64 from "react";
4490
4536
  var HOLD_MS = 3200;
4491
4537
  var CLEAR_MS = HOLD_MS + 900;
4492
4538
  function useFreshHighlight() {
4493
- const [freshId, setFreshId] = React63.useState(null);
4494
- const [message, setMessage] = React63.useState("");
4495
- const timer = React63.useRef(void 0);
4496
- React63.useEffect(() => () => clearTimeout(timer.current), []);
4497
- const markFresh = React63.useCallback((id, announce) => {
4539
+ const [freshId, setFreshId] = React64.useState(null);
4540
+ const [message, setMessage] = React64.useState("");
4541
+ const timer = React64.useRef(void 0);
4542
+ React64.useEffect(() => () => clearTimeout(timer.current), []);
4543
+ const markFresh = React64.useCallback((id, announce) => {
4498
4544
  clearTimeout(timer.current);
4499
4545
  setFreshId(id);
4500
4546
  if (announce) setMessage(announce);
4501
4547
  timer.current = setTimeout(() => setFreshId(null), CLEAR_MS);
4502
4548
  }, []);
4503
- const isFresh = React63.useCallback((id) => id === freshId, [freshId]);
4504
- const freshRef = React63.useCallback((el) => {
4549
+ const isFresh = React64.useCallback((id) => id === freshId, [freshId]);
4550
+ const freshRef = React64.useCallback((el) => {
4505
4551
  if (!el) return;
4506
4552
  const rect = el.getBoundingClientRect();
4507
4553
  const viewportH = window.innerHeight || document.documentElement.clientHeight;
@@ -4510,7 +4556,7 @@ function useFreshHighlight() {
4510
4556
  const reduce = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
4511
4557
  el.scrollIntoView({ block: "nearest", behavior: reduce ? "auto" : "smooth" });
4512
4558
  }, []);
4513
- const announcer = React63.createElement(
4559
+ const announcer = React64.createElement(
4514
4560
  "span",
4515
4561
  { role: "status", "aria-live": "polite", className: "sr-only" },
4516
4562
  message
@@ -4518,12 +4564,64 @@ function useFreshHighlight() {
4518
4564
  return { isFresh, markFresh, freshRef, announcer };
4519
4565
  }
4520
4566
 
4567
+ // src/components/quick-search-row.tsx
4568
+ import { Search as Search2 } from "lucide-react";
4569
+ import { jsx as jsx75, jsxs as jsxs49 } from "react/jsx-runtime";
4570
+ function QuickSearchRow({
4571
+ onOpen,
4572
+ label = "Quick search",
4573
+ shortcut = "\u2318K",
4574
+ collapsed = false,
4575
+ icon
4576
+ }) {
4577
+ const name = shortcut ? `${label} ${shortcut}` : label;
4578
+ if (!collapsed) {
4579
+ return /* @__PURE__ */ jsxs49(
4580
+ "button",
4581
+ {
4582
+ type: "button",
4583
+ onClick: onOpen,
4584
+ "aria-label": name,
4585
+ className: cn(
4586
+ // `bg-bg-overlay` where every other field in the kit takes `bg-bg-primary`, because every
4587
+ // other field sits on a card or a page and this one sits on the rail — which IS
4588
+ // `bg-bg-primary`, so the field's own fill would be its ground and only the border would
4589
+ // say it is there. Lifted, it is 1.073:1 above the rail in light and 1.184:1 in dark
4590
+ // (`Guidelines/Look/Surface tone`), and the field edge still reads at 2.348 and 2.611.
4591
+ "flex h-9 w-full cursor-pointer items-center gap-2 rounded-md border border-field-border bg-bg-overlay px-2.5",
4592
+ "text-left text-sm text-text-tertiary transition-colors duration-fast",
4593
+ "hover:border-field-border-hover hover:text-text-secondary",
4594
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
4595
+ ),
4596
+ children: [
4597
+ /* @__PURE__ */ jsx75("span", { className: "flex size-4 shrink-0 items-center justify-center [&_svg]:size-4", "aria-hidden": "true", children: icon ?? /* @__PURE__ */ jsx75(Search2, {}) }),
4598
+ /* @__PURE__ */ jsx75("span", { className: "min-w-0 flex-1 truncate", children: label }),
4599
+ shortcut && /* @__PURE__ */ jsx75("span", { className: "shrink-0 text-xs font-medium text-text-tertiary", children: shortcut })
4600
+ ]
4601
+ }
4602
+ );
4603
+ }
4604
+ return /* @__PURE__ */ jsxs49(Tooltip, { children: [
4605
+ /* @__PURE__ */ jsx75(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx75(
4606
+ NavRow,
4607
+ {
4608
+ variant: "rail",
4609
+ icon: icon ?? /* @__PURE__ */ jsx75(Search2, { "aria-hidden": "true" }),
4610
+ label,
4611
+ onClick: onOpen
4612
+ }
4613
+ ) }),
4614
+ /* @__PURE__ */ jsx75(TooltipContent, { side: "right", children: name })
4615
+ ] });
4616
+ }
4617
+ QuickSearchRow.displayName = "QuickSearchRow";
4618
+
4521
4619
  // src/components/nav-section-label.tsx
4522
- import * as React64 from "react";
4523
- import { jsx as jsx75 } from "react/jsx-runtime";
4524
- var NavSectionLabel = React64.forwardRef(
4620
+ import * as React65 from "react";
4621
+ import { jsx as jsx76 } from "react/jsx-runtime";
4622
+ var NavSectionLabel = React65.forwardRef(
4525
4623
  function NavSectionLabel2({ className, ...props }, ref) {
4526
- return /* @__PURE__ */ jsx75(
4624
+ return /* @__PURE__ */ jsx76(
4527
4625
  "div",
4528
4626
  {
4529
4627
  ref,
@@ -4536,8 +4634,8 @@ var NavSectionLabel = React64.forwardRef(
4536
4634
  NavSectionLabel.displayName = "NavSectionLabel";
4537
4635
 
4538
4636
  // src/components/menu-popup.tsx
4539
- import * as React65 from "react";
4540
- import { jsx as jsx76, jsxs as jsxs49 } from "react/jsx-runtime";
4637
+ import * as React66 from "react";
4638
+ import { jsx as jsx77, jsxs as jsxs50 } from "react/jsx-runtime";
4541
4639
  function MenuPopup({
4542
4640
  trigger,
4543
4641
  children,
@@ -4549,9 +4647,9 @@ function MenuPopup({
4549
4647
  sideOffset = 6,
4550
4648
  className
4551
4649
  }) {
4552
- return /* @__PURE__ */ jsxs49(Popover, { open, defaultOpen, onOpenChange, children: [
4553
- /* @__PURE__ */ jsx76(PopoverTrigger, { asChild: true, children: trigger }),
4554
- /* @__PURE__ */ jsx76(
4650
+ return /* @__PURE__ */ jsxs50(Popover, { open, defaultOpen, onOpenChange, children: [
4651
+ /* @__PURE__ */ jsx77(PopoverTrigger, { asChild: true, children: trigger }),
4652
+ /* @__PURE__ */ jsx77(
4555
4653
  PopoverContent,
4556
4654
  {
4557
4655
  side: direction === "up" ? "top" : "bottom",
@@ -4566,9 +4664,9 @@ function MenuPopup({
4566
4664
  )
4567
4665
  ] });
4568
4666
  }
4569
- var MenuDivider = React65.forwardRef(
4667
+ var MenuDivider = React66.forwardRef(
4570
4668
  function MenuDivider2({ className, ...props }, ref) {
4571
- return /* @__PURE__ */ jsx76(
4669
+ return /* @__PURE__ */ jsx77(
4572
4670
  "div",
4573
4671
  {
4574
4672
  ref,
@@ -4582,72 +4680,86 @@ var MenuDivider = React65.forwardRef(
4582
4680
  MenuDivider.displayName = "MenuDivider";
4583
4681
 
4584
4682
  // src/components/sidebar-product-header.tsx
4585
- import * as React66 from "react";
4586
- import { Slot as Slot4 } from "@radix-ui/react-slot";
4683
+ import * as React67 from "react";
4684
+ import { Slot as Slot3 } from "@radix-ui/react-slot";
4587
4685
  import { ChevronsUpDown as ChevronsUpDown2 } from "lucide-react";
4588
- import { Fragment as Fragment7, jsx as jsx77, jsxs as jsxs50 } from "react/jsx-runtime";
4589
- var SidebarProductHeader = React66.forwardRef(
4686
+ import { Fragment as Fragment7, jsx as jsx78, jsxs as jsxs51 } from "react/jsx-runtime";
4687
+ var SidebarProductHeader = React67.forwardRef(
4590
4688
  function SidebarProductHeader2({ name, icon, trailing, asChild = false, className, children, ...props }, ref) {
4591
- const adornment = trailing === void 0 ? /* @__PURE__ */ jsx77(ChevronsUpDown2, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }) : trailing;
4592
- const content = /* @__PURE__ */ jsxs50(Fragment7, { children: [
4593
- icon && /* @__PURE__ */ jsx77("span", { className: "flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md", "aria-hidden": "true", children: icon }),
4594
- /* @__PURE__ */ jsx77("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-text-primary", children: name }),
4595
- adornment && /* @__PURE__ */ jsx77("span", { className: "flex shrink-0 items-center", children: adornment })
4689
+ const adornment = trailing === void 0 ? /* @__PURE__ */ jsx78(ChevronsUpDown2, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }) : trailing;
4690
+ const content = /* @__PURE__ */ jsxs51(Fragment7, { children: [
4691
+ icon && /* @__PURE__ */ jsx78("span", { className: "flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md", "aria-hidden": "true", children: icon }),
4692
+ /* @__PURE__ */ jsx78("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-text-primary", children: name }),
4693
+ adornment && /* @__PURE__ */ jsx78("span", { className: "flex shrink-0 items-center", children: adornment })
4596
4694
  ] });
4597
- const classes = cn("flex w-full items-center gap-2.5 rounded-xl px-1.5 py-0 text-left", className);
4695
+ const classes = cn("flex w-full cursor-pointer items-center gap-2.5 rounded-xl px-1.5 py-0 text-left", className);
4598
4696
  if (asChild) {
4599
- const child = React66.Children.only(children);
4600
- return /* @__PURE__ */ jsx77(Slot4, { ref, className: classes, ...props, children: React66.cloneElement(child, void 0, content) });
4697
+ const child = React67.Children.only(children);
4698
+ return /* @__PURE__ */ jsx78(Slot3, { ref, className: classes, ...props, children: React67.cloneElement(child, void 0, content) });
4601
4699
  }
4602
- return /* @__PURE__ */ jsx77("button", { ref, type: "button", className: classes, ...props, children: content });
4700
+ return /* @__PURE__ */ jsx78("button", { ref, type: "button", className: classes, ...props, children: content });
4603
4701
  }
4604
4702
  );
4605
4703
  SidebarProductHeader.displayName = "SidebarProductHeader";
4606
4704
 
4607
4705
  // src/components/org-product-switcher.tsx
4608
- import { ChevronsUpDown as ChevronsUpDown3, Check as Check9 } from "lucide-react";
4609
- import { Fragment as Fragment8, jsx as jsx78, jsxs as jsxs51 } from "react/jsx-runtime";
4610
- var triggerBox = "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-1 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
4706
+ import * as React68 from "react";
4707
+ import { ChevronsUpDown as ChevronsUpDown3, Check as Check9, Search as Search3 } from "lucide-react";
4708
+ import { Fragment as Fragment8, jsx as jsx79, jsxs as jsxs52 } from "react/jsx-runtime";
4709
+ var PRODUCT_STATUS_LABEL = {
4710
+ blocked: "Blocked",
4711
+ archived: "Archived"
4712
+ };
4713
+ function productStatusBadge(status) {
4714
+ if (status === "active") return void 0;
4715
+ return /* @__PURE__ */ jsx79(Badge, { variant: "status", children: PRODUCT_STATUS_LABEL[status] });
4716
+ }
4717
+ var triggerBox = "flex min-h-[40px] w-full items-center gap-2.5 rounded-xl px-1.5 py-1 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
4718
+ var inlineTriggerBox = "flex items-center gap-1.5 rounded-lg px-2 py-1 text-sm font-semibold text-text-primary transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
4611
4719
  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";
4612
4720
  var sectionLabel = "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary";
4721
+ var searchBox = "mx-1 mb-1 flex h-8 shrink-0 items-center gap-2 rounded-md border border-field-border bg-bg-primary px-2 focus-within:ring-2 focus-within:ring-border-focus";
4722
+ var rowScroller = "flex max-h-[18rem] min-h-0 flex-col gap-px overflow-y-auto overscroll-contain";
4613
4723
  var NO_ORG_LABEL = "Select an organization\u2026";
4614
4724
  var nameOf = (item) => item?.name.trim() ? item.name : void 0;
4615
4725
  var UNNAMED = { organization: "Unnamed organization", product: "Unnamed product" };
4726
+ function NameLine({ className, children }) {
4727
+ return /* @__PURE__ */ jsxs52("span", { className: "flex min-w-0 items-center gap-1", children: [
4728
+ /* @__PURE__ */ jsx79("span", { className: cn("min-w-0 truncate text-sm leading-[normal]", className), children }),
4729
+ /* @__PURE__ */ jsx79(ChevronsUpDown3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
4730
+ ] });
4731
+ }
4732
+ var SEARCH_NOUN = { organization: "organizations", product: "products" };
4616
4733
  function ItemLabel({ item, kind }) {
4617
4734
  const name = nameOf(item);
4618
- return /* @__PURE__ */ jsx78("span", { className: cn("min-w-0 flex-1 truncate", !name && "text-text-tertiary"), children: name ?? UNNAMED[kind] });
4735
+ return /* @__PURE__ */ jsx79("span", { className: cn("min-w-0 flex-1 truncate", !name && "text-text-tertiary"), children: name ?? UNNAMED[kind] });
4619
4736
  }
4620
- function Mark2({ item, size, reserve }) {
4621
- const box = size === "md" ? "size-7" : "size-5";
4737
+ var MARK_SIZE = { md: "sm", sm: "xs" };
4738
+ var ICON_BOX = { md: "size-8 rounded-md", sm: "size-6 rounded-sm" };
4739
+ function Mark2({ item, kind, size, reserve }) {
4622
4740
  if (item.icon) {
4623
- return /* @__PURE__ */ jsx78("span", { className: cn("flex shrink-0 items-center justify-center overflow-hidden rounded-md", box), "aria-hidden": "true", children: item.icon });
4741
+ return /* @__PURE__ */ jsx79("span", { className: cn("flex shrink-0 items-center justify-center overflow-hidden", ICON_BOX[size]), "aria-hidden": "true", children: item.icon });
4624
4742
  }
4625
- const initial = nameOf(item)?.trim().charAt(0).toUpperCase();
4626
- if (!initial) return reserve ? /* @__PURE__ */ jsx78("span", { "aria-hidden": "true", className: cn("shrink-0", box) }) : null;
4627
- return /* @__PURE__ */ jsx78(
4628
- "span",
4629
- {
4630
- "aria-hidden": "true",
4631
- className: cn(
4632
- "flex shrink-0 items-center justify-center rounded-md bg-[var(--menu-hov)] font-semibold text-text-secondary",
4633
- box,
4634
- size === "md" ? "text-sm" : "text-xs"
4635
- ),
4636
- children: initial
4637
- }
4638
- );
4743
+ const name = nameOf(item);
4744
+ if (!name) return reserve ? /* @__PURE__ */ jsx79("span", { "aria-hidden": "true", className: cn("shrink-0", ICON_BOX[size]) }) : null;
4745
+ return /* @__PURE__ */ jsx79(EntityTile, { name, tone: kind === "product" ? "auto" : "neutral", size: MARK_SIZE[size] });
4639
4746
  }
4640
4747
  function OrgProductSwitcher({
4641
- organizations,
4748
+ organizations = [],
4642
4749
  activeOrgId,
4643
4750
  onOrgSelect,
4644
4751
  products = [],
4645
4752
  activeProductId,
4646
4753
  onProductSelect,
4647
4754
  actions,
4755
+ trigger = "stacked",
4648
4756
  className,
4649
4757
  ...props
4650
4758
  }) {
4759
+ const [open, setOpen] = React68.useState(false);
4760
+ const [query, setQuery] = React68.useState("");
4761
+ const contentRef = React68.useRef(null);
4762
+ const searchRef = React68.useRef(null);
4651
4763
  const activeOrg = organizations.find((o) => o.id === activeOrgId);
4652
4764
  const activeProduct = products.find((p) => p.id === activeProductId);
4653
4765
  const orgName = nameOf(activeOrg);
@@ -4655,63 +4767,112 @@ function OrgProductSwitcher({
4655
4767
  const orgLevel = !activeProduct;
4656
4768
  const productLabel = activeProduct && (productName ?? UNNAMED.product);
4657
4769
  const markItem = activeProduct?.icon || productName ? activeProduct : activeOrg;
4770
+ const markKind = markItem === activeProduct ? "product" : "organization";
4658
4771
  const trail = [orgName, productLabel].filter(Boolean).join(" / ");
4659
4772
  const ariaLabel = props["aria-label"] ?? (trail || NO_ORG_LABEL);
4660
- return /* @__PURE__ */ jsxs51(DropdownMenu, { children: [
4661
- /* @__PURE__ */ jsxs51(DropdownMenuTrigger, { "aria-label": ariaLabel, className: cn(triggerBox, className), children: [
4662
- markItem && /* @__PURE__ */ jsx78(Mark2, { item: markItem, size: "md" }),
4663
- orgLevel ? /* @__PURE__ */ jsx78("span", { className: "flex min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsx78(
4664
- "span",
4665
- {
4666
- className: cn(
4667
- "truncate text-sm leading-[normal]",
4668
- orgName ? "font-semibold text-text-primary" : "text-text-tertiary"
4669
- ),
4670
- children: orgName ?? NO_ORG_LABEL
4671
- }
4672
- ) }) : /* @__PURE__ */ jsxs51("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
4673
- orgName && /* @__PURE__ */ jsx78("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: orgName }),
4674
- /* @__PURE__ */ jsx78(
4675
- "span",
4676
- {
4677
- className: cn(
4678
- "truncate text-sm leading-[normal]",
4679
- productName ? "font-semibold text-text-primary" : "text-text-tertiary"
4680
- ),
4681
- children: productLabel
4682
- }
4683
- )
4684
- ] }),
4685
- /* @__PURE__ */ jsx78(ChevronsUpDown3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
4773
+ const inlineName = productLabel ?? orgName;
4774
+ const menuKind = organizations.length > 0 ? "organization" : "product";
4775
+ const items = menuKind === "organization" ? organizations : products;
4776
+ const activeItemId = menuKind === "organization" ? activeOrgId : activeProductId;
4777
+ const triggerMark = menuKind === "organization" && markItem;
4778
+ const noun = SEARCH_NOUN[menuKind];
4779
+ const searchLabel = items.length > 1 ? `Search ${items.length} ${noun}` : `Search ${noun}`;
4780
+ const needle = query.trim().toLowerCase();
4781
+ const matches = needle ? items.filter((i) => (nameOf(i) ?? UNNAMED[menuKind]).toLowerCase().includes(needle)) : items;
4782
+ const hasList = items.length > 0;
4783
+ React68.useEffect(() => {
4784
+ if (!open || !hasList) return;
4785
+ const id = window.setTimeout(() => searchRef.current?.focus());
4786
+ return () => window.clearTimeout(id);
4787
+ }, [open, hasList]);
4788
+ const setMenuOpen = (next) => {
4789
+ setOpen(next);
4790
+ if (!next) setQuery("");
4791
+ };
4792
+ const pick = (id) => {
4793
+ setMenuOpen(false);
4794
+ if (menuKind === "organization") onOrgSelect?.(id);
4795
+ else onProductSelect?.(id);
4796
+ };
4797
+ const onSearchKeyDown = (e) => {
4798
+ if (e.key === "ArrowDown") {
4799
+ e.preventDefault();
4800
+ contentRef.current?.querySelector("[data-menu-row]")?.focus();
4801
+ return;
4802
+ }
4803
+ if (e.key === "Enter") {
4804
+ const first = matches[0];
4805
+ if (first) {
4806
+ e.preventDefault();
4807
+ pick(first.id);
4808
+ }
4809
+ return;
4810
+ }
4811
+ if (e.key.length === 1) e.stopPropagation();
4812
+ };
4813
+ return /* @__PURE__ */ jsxs52(DropdownMenu, { open, onOpenChange: setMenuOpen, children: [
4814
+ trigger === "inline" ? (
4815
+ // One line, and the words are the whole trigger: the product where one has resolved, the
4816
+ // org where it has not, and the same tertiary placeholder as the stacked form where neither
4817
+ // has. Nothing is truncated — a bar sizes to its contents, and a name cut short in a bar is
4818
+ // a name nowhere else on the page repeats.
4819
+ /* @__PURE__ */ jsxs52(DropdownMenuTrigger, { "aria-label": ariaLabel, className: cn(inlineTriggerBox, className), children: [
4820
+ /* @__PURE__ */ jsx79("span", { className: cn(!inlineName && "font-medium text-text-tertiary"), children: inlineName ?? NO_ORG_LABEL }),
4821
+ /* @__PURE__ */ jsx79(ChevronsUpDown3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
4822
+ ] })
4823
+ ) : /* @__PURE__ */ jsxs52(DropdownMenuTrigger, { "aria-label": ariaLabel, className: cn(triggerBox, className), children: [
4824
+ triggerMark && /* @__PURE__ */ jsx79(Mark2, { item: triggerMark, kind: markKind, size: "md" }),
4825
+ orgLevel ? /* @__PURE__ */ jsx79("span", { className: "flex min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsx79(NameLine, { className: orgName ? "font-semibold text-text-primary" : "text-text-tertiary", children: orgName ?? NO_ORG_LABEL }) }) : /* @__PURE__ */ jsxs52("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
4826
+ orgName && /* @__PURE__ */ jsx79("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: orgName }),
4827
+ /* @__PURE__ */ jsx79(NameLine, { className: productName ? "font-semibold text-text-primary" : "text-text-tertiary", children: productLabel })
4828
+ ] })
4686
4829
  ] }),
4687
- /* @__PURE__ */ jsxs51(
4830
+ /* @__PURE__ */ jsxs52(
4688
4831
  DropdownMenuContent,
4689
4832
  {
4833
+ ref: contentRef,
4690
4834
  align: "start",
4691
4835
  sideOffset: 6,
4692
- className: "flex w-[var(--radix-dropdown-menu-trigger-width)] min-w-56 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
4836
+ className: "flex w-[var(--radix-dropdown-menu-trigger-width)] min-w-64 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
4693
4837
  children: [
4694
- /* @__PURE__ */ jsx78(DropdownMenuLabel, { className: sectionLabel, children: "Organizations" }),
4695
- organizations.map((o) => /* @__PURE__ */ jsxs51(DropdownMenuItem, { className: menuItem, onSelect: () => onOrgSelect(o.id), children: [
4696
- /* @__PURE__ */ jsx78(Mark2, { item: o, size: "sm", reserve: true }),
4697
- /* @__PURE__ */ jsx78(ItemLabel, { item: o, kind: "organization" }),
4698
- o.id === activeOrgId && /* @__PURE__ */ jsx78(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
4699
- ] }, o.id)),
4700
- products.length > 0 && /* @__PURE__ */ jsxs51(Fragment8, { children: [
4701
- /* @__PURE__ */ jsx78(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
4702
- /* @__PURE__ */ jsx78(DropdownMenuLabel, { className: sectionLabel, children: orgName ? `${orgName} \xB7 Products` : "Products" }),
4703
- products.map((p) => /* @__PURE__ */ jsxs51(DropdownMenuItem, { className: menuItem, onSelect: () => onProductSelect?.(p.id), children: [
4704
- /* @__PURE__ */ jsx78(Mark2, { item: p, size: "sm", reserve: true }),
4705
- /* @__PURE__ */ jsx78(ItemLabel, { item: p, kind: "product" }),
4706
- p.id === activeProductId && /* @__PURE__ */ jsx78(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
4707
- ] }, p.id))
4838
+ items.length > 0 && /* @__PURE__ */ jsxs52(Fragment8, { children: [
4839
+ /* @__PURE__ */ jsx79(DropdownMenuLabel, { className: sectionLabel, children: menuKind === "organization" ? "Organizations" : "Products" }),
4840
+ /* @__PURE__ */ jsxs52("div", { className: searchBox, onKeyDown: onSearchKeyDown, children: [
4841
+ /* @__PURE__ */ jsx79(Search3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }),
4842
+ /* @__PURE__ */ jsx79(
4843
+ "input",
4844
+ {
4845
+ ref: searchRef,
4846
+ type: "text",
4847
+ value: query,
4848
+ onChange: (e) => setQuery(e.target.value),
4849
+ placeholder: searchLabel,
4850
+ "aria-label": searchLabel,
4851
+ className: "min-w-0 flex-1 bg-transparent text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none"
4852
+ }
4853
+ )
4854
+ ] }),
4855
+ /* @__PURE__ */ jsx79("div", { role: "group", className: rowScroller, children: matches.map((item) => {
4856
+ const status = menuKind === "product" && productStatusBadge(item.status ?? "active");
4857
+ return /* @__PURE__ */ jsxs52(DropdownMenuItem, { "data-menu-row": "", className: menuItem, onSelect: () => pick(item.id), children: [
4858
+ /* @__PURE__ */ jsx79(Mark2, { item, kind: menuKind, size: "sm", reserve: true }),
4859
+ /* @__PURE__ */ jsx79(ItemLabel, { item, kind: menuKind }),
4860
+ status && /* @__PURE__ */ jsx79("span", { className: "shrink-0", children: status }),
4861
+ item.id === activeItemId && /* @__PURE__ */ jsx79(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
4862
+ ] }, item.id);
4863
+ }) }),
4864
+ matches.length === 0 && /* @__PURE__ */ jsxs52("div", { className: "px-2 py-1.5 text-sm text-text-tertiary", children: [
4865
+ "No ",
4866
+ noun,
4867
+ " match."
4868
+ ] })
4708
4869
  ] }),
4709
- actions && actions.length > 0 && /* @__PURE__ */ jsxs51(Fragment8, { children: [
4710
- /* @__PURE__ */ jsx78(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
4711
- actions.map((a) => /* @__PURE__ */ jsx78(DropdownMenuItem, { className: menuItem, onSelect: a.onSelect, asChild: Boolean(a.href), children: a.href ? /* @__PURE__ */ jsxs51("a", { href: a.href, children: [
4870
+ actions && actions.length > 0 && /* @__PURE__ */ jsxs52(Fragment8, { children: [
4871
+ items.length > 0 && /* @__PURE__ */ jsx79(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
4872
+ actions.map((a) => /* @__PURE__ */ jsx79(DropdownMenuItem, { className: menuItem, onSelect: a.onSelect, asChild: Boolean(a.href), children: a.href ? /* @__PURE__ */ jsxs52("a", { href: a.href, children: [
4712
4873
  a.icon,
4713
4874
  a.label
4714
- ] }) : /* @__PURE__ */ jsxs51(Fragment8, { children: [
4875
+ ] }) : /* @__PURE__ */ jsxs52(Fragment8, { children: [
4715
4876
  a.icon,
4716
4877
  a.label
4717
4878
  ] }) }, a.id))
@@ -4725,12 +4886,13 @@ OrgProductSwitcher.displayName = "OrgProductSwitcher";
4725
4886
 
4726
4887
  // src/components/sidebar-back-header.tsx
4727
4888
  import { ArrowLeft as ArrowLeft3 } from "lucide-react";
4728
- import { jsx as jsx79, jsxs as jsxs52 } from "react/jsx-runtime";
4889
+ import { jsx as jsx80, jsxs as jsxs53 } from "react/jsx-runtime";
4729
4890
  var focusRing = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
4730
4891
  var arrowPlate = "flex size-5 items-center justify-center rounded-md transition-colors duration-fast hover:bg-[color-mix(in_srgb,var(--text-primary)_12%,transparent)] hover:text-text-primary";
4892
+ var rowPlate = "transition-colors duration-fast hover:bg-[color-mix(in_srgb,var(--text-primary)_7%,transparent)]";
4731
4893
  var arrowBox = "flex shrink-0 cursor-pointer items-center rounded-xl py-2 pr-0 pl-2.5 text-text-secondary";
4732
4894
  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";
4733
- var Arrow = () => /* @__PURE__ */ jsx79(ArrowLeft3, { size: 16, "aria-hidden": "true" });
4895
+ var Arrow = () => /* @__PURE__ */ jsx80(ArrowLeft3, { size: 16, "aria-hidden": "true" });
4734
4896
  function SidebarBackHeader({
4735
4897
  title,
4736
4898
  onBack,
@@ -4744,22 +4906,22 @@ function SidebarBackHeader({
4744
4906
  const { className: arrowClassName, ...arrowRest } = arrowProps ?? {};
4745
4907
  const { className: titleClassName, ...titleRest } = titleProps ?? {};
4746
4908
  if (!onTitleClick) {
4747
- return /* @__PURE__ */ jsxs52(
4909
+ return /* @__PURE__ */ jsxs53(
4748
4910
  "button",
4749
4911
  {
4750
4912
  type: "button",
4751
4913
  onClick: onBack,
4752
- className: cn("flex items-center rounded-xl", focusRing, className),
4914
+ className: cn("flex cursor-pointer items-center rounded-xl", rowPlate, focusRing, className),
4753
4915
  ...rowProps,
4754
4916
  children: [
4755
- /* @__PURE__ */ jsx79("span", { className: arrowBox, children: /* @__PURE__ */ jsx79("span", { className: cn(arrowPlate, arrowClassName), ...arrowRest, children: /* @__PURE__ */ jsx79(Arrow, {}) }) }),
4756
- /* @__PURE__ */ jsx79("span", { className: cn(titleBox, titleClassName), ...titleRest, children: title })
4917
+ /* @__PURE__ */ jsx80("span", { className: arrowBox, children: /* @__PURE__ */ jsx80("span", { className: cn(arrowPlate, arrowClassName), ...arrowRest, children: /* @__PURE__ */ jsx80(Arrow, {}) }) }),
4918
+ /* @__PURE__ */ jsx80("span", { className: cn(titleBox, titleClassName), ...titleRest, children: title })
4757
4919
  ]
4758
4920
  }
4759
4921
  );
4760
4922
  }
4761
- return /* @__PURE__ */ jsxs52("div", { className: cn("flex items-center", className), ...rowProps, children: [
4762
- /* @__PURE__ */ jsx79(
4923
+ return /* @__PURE__ */ jsxs53("div", { className: cn("flex items-center rounded-xl", rowPlate, className), ...rowProps, children: [
4924
+ /* @__PURE__ */ jsx80(
4763
4925
  "button",
4764
4926
  {
4765
4927
  type: "button",
@@ -4767,10 +4929,10 @@ function SidebarBackHeader({
4767
4929
  onClick: onBack,
4768
4930
  className: cn(arrowBox, focusRing, arrowClassName),
4769
4931
  ...arrowRest,
4770
- children: /* @__PURE__ */ jsx79("span", { className: arrowPlate, children: /* @__PURE__ */ jsx79(Arrow, {}) })
4932
+ children: /* @__PURE__ */ jsx80("span", { className: arrowPlate, children: /* @__PURE__ */ jsx80(Arrow, {}) })
4771
4933
  }
4772
4934
  ),
4773
- /* @__PURE__ */ jsx79(
4935
+ /* @__PURE__ */ jsx80(
4774
4936
  "button",
4775
4937
  {
4776
4938
  type: "button",
@@ -4785,34 +4947,23 @@ function SidebarBackHeader({
4785
4947
  SidebarBackHeader.displayName = "SidebarBackHeader";
4786
4948
 
4787
4949
  // src/components/top-bar.tsx
4788
- import * as React67 from "react";
4789
- import { jsx as jsx80, jsxs as jsxs53 } from "react/jsx-runtime";
4790
- var TopBar = React67.forwardRef(
4791
- ({ left, right, className, ...props }, ref) => /* @__PURE__ */ jsxs53("div", { ref, className: cn("flex w-full items-center gap-1", className), ...props, children: [
4950
+ import * as React69 from "react";
4951
+ import { jsx as jsx81, jsxs as jsxs54 } from "react/jsx-runtime";
4952
+ var TopBar = React69.forwardRef(
4953
+ ({ left, right, className, ...props }, ref) => /* @__PURE__ */ jsxs54("div", { ref, className: cn("flex w-full items-center gap-1", className), ...props, children: [
4792
4954
  left,
4793
- right && /* @__PURE__ */ jsx80("div", { className: "ml-auto flex items-center gap-2", children: right })
4955
+ right && /* @__PURE__ */ jsx81("div", { className: "ml-auto flex items-center gap-2", children: right })
4794
4956
  ] })
4795
4957
  );
4796
4958
  TopBar.displayName = "TopBar";
4797
4959
 
4798
- // src/components/top-bar-utilities.tsx
4799
- import * as React68 from "react";
4800
- import { jsx as jsx81, jsxs as jsxs54 } from "react/jsx-runtime";
4801
- var TopBarUtilities = React68.forwardRef(
4802
- ({ items, className, ...props }, ref) => /* @__PURE__ */ jsx81("div", { ref, className: cn("flex items-center gap-1", className), ...props, children: items.map(({ name, icon, onClick }) => /* @__PURE__ */ jsxs54(Tooltip, { children: [
4803
- /* @__PURE__ */ jsx81(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx81(Button, { variant: "ghost", size: "sm", icon, "aria-label": name, onClick }) }),
4804
- /* @__PURE__ */ jsx81(TooltipContent, { children: name })
4805
- ] }, name)) })
4806
- );
4807
- TopBarUtilities.displayName = "TopBarUtilities";
4808
-
4809
4960
  // src/components/grid.tsx
4810
- import * as React69 from "react";
4811
- import { Slot as Slot5 } from "@radix-ui/react-slot";
4961
+ import * as React70 from "react";
4962
+ import { Slot as Slot4 } from "@radix-ui/react-slot";
4812
4963
  import { jsx as jsx82 } from "react/jsx-runtime";
4813
- var Grid = React69.forwardRef(
4964
+ var Grid = React70.forwardRef(
4814
4965
  ({ fluid = false, asChild = false, className, ...props }, ref) => {
4815
- const Comp = asChild ? Slot5 : "div";
4966
+ const Comp = asChild ? Slot4 : "div";
4816
4967
  return /* @__PURE__ */ jsx82(
4817
4968
  Comp,
4818
4969
  {
@@ -4831,8 +4982,8 @@ var Grid = React69.forwardRef(
4831
4982
  Grid.displayName = "Grid";
4832
4983
 
4833
4984
  // src/components/col.tsx
4834
- import * as React70 from "react";
4835
- import { Slot as Slot6 } from "@radix-ui/react-slot";
4985
+ import * as React71 from "react";
4986
+ import { Slot as Slot5 } from "@radix-ui/react-slot";
4836
4987
  import { jsx as jsx83 } from "react/jsx-runtime";
4837
4988
  var TIER_MAX = { base: 4, md: 8, xl: 12 };
4838
4989
  var SPAN = {
@@ -4953,9 +5104,9 @@ function responsiveClasses(span, offset) {
4953
5104
  }
4954
5105
  return cn(...spanClasses, ...startClasses);
4955
5106
  }
4956
- var Col = React70.forwardRef(
5107
+ var Col = React71.forwardRef(
4957
5108
  ({ span, offset, asChild = false, className, ...props }, ref) => {
4958
- const Comp = asChild ? Slot6 : "div";
5109
+ const Comp = asChild ? Slot5 : "div";
4959
5110
  return /* @__PURE__ */ jsx83(Comp, { ref, className: cn(responsiveClasses(span, offset), className), ...props });
4960
5111
  }
4961
5112
  );
@@ -4972,7 +5123,7 @@ function PageColumn({ className, width = "reading", ...props }) {
4972
5123
  }
4973
5124
 
4974
5125
  // src/components/code-block.tsx
4975
- import * as React71 from "react";
5126
+ import * as React72 from "react";
4976
5127
  import { jsx as jsx85, jsxs as jsxs55 } from "react/jsx-runtime";
4977
5128
  var TOKEN_CLASS = {
4978
5129
  comment: "text-text-tertiary italic",
@@ -5144,11 +5295,11 @@ function dropLeading(tokens, count) {
5144
5295
  }
5145
5296
  return out;
5146
5297
  }
5147
- var CodeBlock = React71.forwardRef(
5298
+ var CodeBlock = React72.forwardRef(
5148
5299
  ({ code, lang = "tsx", variant = "default", copy = false, filename, scroll = false, highlightLines, showLineNumbers = false, className, ...props }, ref) => {
5149
- const lines = React71.useMemo(() => tokenizeLines(code, lang), [code, lang]);
5150
- const rawLines = React71.useMemo(() => code.split("\n"), [code]);
5151
- const highlighted = React71.useMemo(() => parseHighlightLines(highlightLines), [highlightLines]);
5300
+ const lines = React72.useMemo(() => tokenizeLines(code, lang), [code, lang]);
5301
+ const rawLines = React72.useMemo(() => code.split("\n"), [code]);
5302
+ const highlighted = React72.useMemo(() => parseHighlightLines(highlightLines), [highlightLines]);
5152
5303
  const isDiff = variant === "diff";
5153
5304
  const isTerminal = variant === "terminal";
5154
5305
  const showCopy = copy && !isTerminal;
@@ -5223,7 +5374,7 @@ var CodeBlock = React71.forwardRef(
5223
5374
  }
5224
5375
  );
5225
5376
  CodeBlock.displayName = "CodeBlock";
5226
- var Code = React71.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx85(
5377
+ var Code = React72.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx85(
5227
5378
  "code",
5228
5379
  {
5229
5380
  ref,
@@ -5237,10 +5388,10 @@ var Code = React71.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
5237
5388
  Code.displayName = "Code";
5238
5389
 
5239
5390
  // src/components/grid-overlay.tsx
5240
- import * as React72 from "react";
5391
+ import * as React73 from "react";
5241
5392
  import { jsx as jsx86 } from "react/jsx-runtime";
5242
5393
  var BASELINE = "var(--grid-gutter) / 2";
5243
- var GridOverlay = React72.forwardRef(
5394
+ var GridOverlay = React73.forwardRef(
5244
5395
  ({ columns, baseline = false, className, style, ...props }, ref) => {
5245
5396
  const count = Number.isFinite(columns) ? Math.max(1, Math.floor(columns)) : 1;
5246
5397
  return /* @__PURE__ */ jsx86(
@@ -5268,7 +5419,7 @@ var GridOverlay = React72.forwardRef(
5268
5419
  GridOverlay.displayName = "GridOverlay";
5269
5420
 
5270
5421
  // src/components/attachment-chip.tsx
5271
- import * as React73 from "react";
5422
+ import * as React74 from "react";
5272
5423
  import { cva as cva8 } from "class-variance-authority";
5273
5424
  import { Link2, Clock, Plus as Plus2 } from "lucide-react";
5274
5425
  import { jsx as jsx87, jsxs as jsxs56 } from "react/jsx-runtime";
@@ -5290,7 +5441,7 @@ var stateIcons = {
5290
5441
  requested: Clock,
5291
5442
  available: Plus2
5292
5443
  };
5293
- var AttachmentChip = React73.forwardRef(
5444
+ var AttachmentChip = React74.forwardRef(
5294
5445
  ({ state, account, icon, hideIcon = false, className, ...props }, ref) => {
5295
5446
  const Icon = icon ?? stateIcons[state ?? "attached"];
5296
5447
  return /* @__PURE__ */ jsxs56("span", { ref, className: cn(attachmentChipVariants({ state }), className), ...props, children: [
@@ -5302,8 +5453,8 @@ var AttachmentChip = React73.forwardRef(
5302
5453
  AttachmentChip.displayName = "AttachmentChip";
5303
5454
 
5304
5455
  // src/components/connector-card.tsx
5305
- import * as React74 from "react";
5306
- import { AlertTriangle, ChevronDown as ChevronDown6 } from "lucide-react";
5456
+ import * as React75 from "react";
5457
+ import { AlertTriangle, ChevronDown as ChevronDown5 } from "lucide-react";
5307
5458
  import { Fragment as Fragment9, jsx as jsx88, jsxs as jsxs57 } from "react/jsx-runtime";
5308
5459
  var originLabels = {
5309
5460
  org: "Attached by the organization",
@@ -5317,7 +5468,7 @@ var statusLabels = {
5317
5468
  function monogram(name) {
5318
5469
  return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
5319
5470
  }
5320
- var ConnectorCard = React74.forwardRef(
5471
+ var ConnectorCard = React75.forwardRef(
5321
5472
  ({
5322
5473
  name,
5323
5474
  kind,
@@ -5342,7 +5493,7 @@ var ConnectorCard = React74.forwardRef(
5342
5493
  "div",
5343
5494
  {
5344
5495
  "aria-hidden": "true",
5345
- className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-elevated text-sm font-bold text-text-secondary",
5496
+ className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-secondary text-sm font-bold text-text-secondary",
5346
5497
  children: glyph ?? monogram(name)
5347
5498
  }
5348
5499
  );
@@ -5418,7 +5569,7 @@ var ConnectorCard = React74.forwardRef(
5418
5569
  /* @__PURE__ */ jsxs57("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
5419
5570
  statusBadge,
5420
5571
  /* @__PURE__ */ jsx88(
5421
- ChevronDown6,
5572
+ ChevronDown5,
5422
5573
  {
5423
5574
  "aria-hidden": "true",
5424
5575
  className: "size-4 shrink-0 text-text-tertiary transition-transform duration-fast group-data-[state=open]:rotate-180"
@@ -5441,12 +5592,12 @@ var ConnectorCard = React74.forwardRef(
5441
5592
  ConnectorCard.displayName = "ConnectorCard";
5442
5593
 
5443
5594
  // src/components/request-row.tsx
5444
- import * as React75 from "react";
5595
+ import * as React76 from "react";
5445
5596
  import { Fragment as Fragment10, jsx as jsx89, jsxs as jsxs58 } from "react/jsx-runtime";
5446
5597
  function monogram2(name) {
5447
5598
  return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
5448
5599
  }
5449
- var RequestRow = React75.forwardRef(
5600
+ var RequestRow = React76.forwardRef(
5450
5601
  ({ surface, name, state, glyph, subtitle, account, onApprove, onDeny, onRequest, onRevoke, action, className, ...props }, ref) => {
5451
5602
  let controls = action;
5452
5603
  if (controls === void 0) {
@@ -5481,7 +5632,7 @@ var RequestRow = React75.forwardRef(
5481
5632
  "div",
5482
5633
  {
5483
5634
  "aria-hidden": "true",
5484
- className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-elevated text-sm font-bold text-text-secondary",
5635
+ className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-secondary text-sm font-bold text-text-secondary",
5485
5636
  children: glyph ?? monogram2(name)
5486
5637
  }
5487
5638
  ),
@@ -5498,7 +5649,7 @@ var RequestRow = React75.forwardRef(
5498
5649
  RequestRow.displayName = "RequestRow";
5499
5650
 
5500
5651
  // src/components/feedback-button.tsx
5501
- import * as React76 from "react";
5652
+ import * as React77 from "react";
5502
5653
  import { MessageSquare, Loader2 as Loader23, CheckCircle2 } from "lucide-react";
5503
5654
  import { jsx as jsx90, jsxs as jsxs59 } from "react/jsx-runtime";
5504
5655
  var TITLE_MAX = 256;
@@ -5514,15 +5665,15 @@ var DEFAULT_LABELS = {
5514
5665
  };
5515
5666
  function FeedbackButton({ onSubmit, labels, className }) {
5516
5667
  const l = { ...DEFAULT_LABELS, ...labels };
5517
- const uid = React76.useId();
5668
+ const uid = React77.useId();
5518
5669
  const titleId = `${uid}-title`;
5519
5670
  const detailsId = `${uid}-details`;
5520
5671
  const titleErrId = `${uid}-title-error`;
5521
5672
  const detailsErrId = `${uid}-details-error`;
5522
- const [open, setOpen] = React76.useState(false);
5523
- const [status, setStatus] = React76.useState("idle");
5524
- const [title, setTitle] = React76.useState("");
5525
- const [details, setDetails] = React76.useState("");
5673
+ const [open, setOpen] = React77.useState(false);
5674
+ const [status, setStatus] = React77.useState("idle");
5675
+ const [title, setTitle] = React77.useState("");
5676
+ const [details, setDetails] = React77.useState("");
5526
5677
  const titleTooLong = title.length > TITLE_MAX;
5527
5678
  const detailsTooLong = details.length > DETAILS_MAX;
5528
5679
  const titleEmpty = title.trim().length === 0;
@@ -5656,11 +5807,11 @@ function isNotificationSettled(item) {
5656
5807
  }
5657
5808
 
5658
5809
  // src/components/notification-bell.tsx
5659
- import * as React78 from "react";
5810
+ import * as React79 from "react";
5660
5811
  import { BellRing, Settings } from "lucide-react";
5661
5812
 
5662
5813
  // src/components/notification-row.tsx
5663
- import * as React77 from "react";
5814
+ import * as React78 from "react";
5664
5815
 
5665
5816
  // src/components/notification-parts.tsx
5666
5817
  import { Check as Check10 } from "lucide-react";
@@ -5690,12 +5841,12 @@ function DeepLinkControl({
5690
5841
  onClick
5691
5842
  }) {
5692
5843
  const name = rowControlName(link.label, title);
5693
- return link.href ? /* @__PURE__ */ jsx91("a", { href: link.href, "aria-label": name, onClick, className, children: link.label }) : /* @__PURE__ */ jsx91("button", { type: "button", "aria-label": name, onClick, className, children: link.label });
5844
+ return link.href ? /* @__PURE__ */ jsx91("a", { href: link.href, "aria-label": name, onClick, className, children: link.label }) : /* @__PURE__ */ jsx91("button", { type: "button", "aria-label": name, onClick, className: cn("cursor-pointer", className), children: link.label });
5694
5845
  }
5695
5846
 
5696
5847
  // src/components/notification-row.tsx
5697
5848
  import { jsx as jsx92, jsxs as jsxs60 } from "react/jsx-runtime";
5698
- var NotificationRow = React77.forwardRef(
5849
+ var NotificationRow = React78.forwardRef(
5699
5850
  ({ item, onItemClick, onActionClick, onMarkRead, formatAge, className, ...props }, ref) => {
5700
5851
  const settled = isNotificationSettled(item);
5701
5852
  const unread = !settled && !item.read;
@@ -5717,7 +5868,7 @@ var NotificationRow = React77.forwardRef(
5717
5868
  /* @__PURE__ */ jsxs60("div", { className: "flex items-start gap-2.5", children: [
5718
5869
  /* @__PURE__ */ jsxs60("div", { className: "min-w-0 flex-1", children: [
5719
5870
  /* @__PURE__ */ jsxs60("p", { className: "truncate text-xs text-text-tertiary", children: [
5720
- /* @__PURE__ */ jsx92("span", { className: "font-semibold uppercase tracking-wide text-text-secondary", children: item.source }),
5871
+ /* @__PURE__ */ jsx92("span", { className: "font-semibold", children: item.source }),
5721
5872
  item.receipt ? `, ${item.receipt}` : ""
5722
5873
  ] }),
5723
5874
  /* @__PURE__ */ jsx92(
@@ -5726,7 +5877,7 @@ var NotificationRow = React77.forwardRef(
5726
5877
  type: "button",
5727
5878
  onClick: () => onItemClick?.(item),
5728
5879
  className: cn(
5729
- "mt-0.5 block text-left text-sm leading-tight underline-offset-2 hover:underline",
5880
+ "mt-0.5 block cursor-pointer text-left text-sm leading-tight underline-offset-2 hover:underline",
5730
5881
  settled ? "text-text-tertiary" : unread ? "font-semibold text-text-primary" : "text-text-secondary"
5731
5882
  ),
5732
5883
  children: item.title
@@ -5759,6 +5910,7 @@ var NotificationRow = React77.forwardRef(
5759
5910
  onClick: () => onActionClick?.(item, action),
5760
5911
  className: cn(
5761
5912
  rowControlHitArea,
5913
+ "cursor-pointer",
5762
5914
  chip ? "rounded-md px-2.5 py-1 text-xs font-medium transition-colors duration-fast" : "text-xs font-semibold text-text-secondary transition-opacity duration-fast hover:opacity-80",
5763
5915
  action.variant === "primary" && "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover",
5764
5916
  action.variant === "destructive" && "bg-bg-elevated text-text-danger hover:bg-bg-sunken"
@@ -5791,7 +5943,7 @@ NotificationRow.displayName = "NotificationRow";
5791
5943
 
5792
5944
  // src/components/notification-bell.tsx
5793
5945
  import { jsx as jsx93, jsxs as jsxs61 } from "react/jsx-runtime";
5794
- var NotificationBell = React78.forwardRef(
5946
+ var NotificationBell = React79.forwardRef(
5795
5947
  ({
5796
5948
  items,
5797
5949
  unreadCount,
@@ -5819,11 +5971,12 @@ var NotificationBell = React78.forwardRef(
5819
5971
  type: "button",
5820
5972
  "aria-label": "Notifications",
5821
5973
  className: cn(
5822
- "relative flex size-8 items-center justify-center rounded-lg text-text-secondary transition-colors duration-fast hover:bg-bg-elevated hover:text-text-primary data-[state=open]:bg-bg-elevated data-[state=open]:text-text-primary",
5974
+ topBarMarkClass,
5975
+ "data-[state=open]:bg-[var(--hov-bg)] data-[state=open]:text-text-primary",
5823
5976
  className
5824
5977
  ),
5825
5978
  children: [
5826
- /* @__PURE__ */ jsx93(BellRing, { className: "size-[18px]", "aria-hidden": "true" }),
5979
+ /* @__PURE__ */ jsx93(BellRing, { "aria-hidden": "true" }),
5827
5980
  unread > 0 && /* @__PURE__ */ jsx93("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 })
5828
5981
  ]
5829
5982
  }
@@ -5833,7 +5986,10 @@ var NotificationBell = React78.forwardRef(
5833
5986
  {
5834
5987
  align: "end",
5835
5988
  collisionPadding: 12,
5836
- style: { maxHeight: "var(--radix-popover-content-available-height, 32rem)" },
5989
+ style: {
5990
+ maxHeight: "var(--radix-popover-content-available-height, 32rem)",
5991
+ maxWidth: "var(--radix-popover-content-available-width, 380px)"
5992
+ },
5837
5993
  className: "flex w-[380px] flex-col overflow-hidden p-0",
5838
5994
  children: [
5839
5995
  /* @__PURE__ */ jsxs61("div", { className: "flex shrink-0 items-center justify-between px-5 py-3", children: [
@@ -5844,7 +6000,7 @@ var NotificationBell = React78.forwardRef(
5844
6000
  {
5845
6001
  type: "button",
5846
6002
  onClick: () => onMarkAllRead?.(),
5847
- className: "text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
6003
+ className: "cursor-pointer text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
5848
6004
  children: "Mark all read"
5849
6005
  }
5850
6006
  ),
@@ -5854,7 +6010,7 @@ var NotificationBell = React78.forwardRef(
5854
6010
  type: "button",
5855
6011
  "aria-label": "Notification settings",
5856
6012
  onClick: () => onOpenSettings(),
5857
- className: "flex size-6 items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
6013
+ className: "flex size-6 cursor-pointer items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
5858
6014
  children: /* @__PURE__ */ jsx93(Settings, { className: "size-[15px]", "aria-hidden": "true" })
5859
6015
  }
5860
6016
  )
@@ -5877,7 +6033,7 @@ var NotificationBell = React78.forwardRef(
5877
6033
  {
5878
6034
  type: "button",
5879
6035
  onClick: () => onOpenArchive(),
5880
- className: "flex w-full shrink-0 items-center justify-center px-5 py-2.5 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
6036
+ className: "flex w-full shrink-0 cursor-pointer items-center justify-center px-5 py-2.5 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
5881
6037
  children: hidden > 0 ? `Open notifications archive, ${hidden} more` : "Open notifications archive"
5882
6038
  }
5883
6039
  )
@@ -5890,10 +6046,10 @@ var NotificationBell = React78.forwardRef(
5890
6046
  NotificationBell.displayName = "NotificationBell";
5891
6047
 
5892
6048
  // src/components/notification-center.tsx
5893
- import * as React79 from "react";
5894
- import { Check as Check11, Search as Search2 } from "lucide-react";
6049
+ import * as React80 from "react";
6050
+ import { Check as Check11, Search as Search4 } from "lucide-react";
5895
6051
  import { jsx as jsx94, jsxs as jsxs62 } from "react/jsx-runtime";
5896
- var chipBase = "rounded-md px-3 py-1.5 text-sm font-medium transition-colors duration-fast";
6052
+ var chipBase = "cursor-pointer rounded-md px-3 py-1.5 text-sm font-medium transition-colors duration-fast";
5897
6053
  var chipOn = "bg-bg-sunken font-semibold text-text-primary";
5898
6054
  var chipOff = "bg-bg-elevated text-text-secondary hover:text-text-primary";
5899
6055
  function CenterRow({
@@ -5909,7 +6065,7 @@ function CenterRow({
5909
6065
  const age = stamp ? formatAge(stamp) : null;
5910
6066
  return /* @__PURE__ */ jsxs62("article", { className: "group rounded-lg bg-bg-elevated px-4 py-3", children: [
5911
6067
  /* @__PURE__ */ jsxs62("div", { className: "flex items-center gap-2", children: [
5912
- /* @__PURE__ */ jsx94("span", { className: "text-xs font-semibold uppercase tracking-[0.09em] text-text-secondary", children: item.source }),
6068
+ /* @__PURE__ */ jsx94("span", { className: "text-xs font-semibold text-text-tertiary", children: item.source }),
5913
6069
  /* @__PURE__ */ jsx94(Badge, { variant: severityBadgeVariant(item.severity), children: severityLabels[item.severity] }),
5914
6070
  (age || markable) && /* @__PURE__ */ jsxs62("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
5915
6071
  stamp && age && /* @__PURE__ */ jsx94(
@@ -5929,7 +6085,7 @@ function CenterRow({
5929
6085
  type: "button",
5930
6086
  onClick: () => onItemClick?.(item),
5931
6087
  className: cn(
5932
- "mt-1 block text-left text-sm leading-snug underline-offset-2 hover:underline",
6088
+ "mt-1 block cursor-pointer text-left text-sm leading-snug underline-offset-2 hover:underline",
5933
6089
  unread ? "font-semibold text-text-primary" : "font-medium text-text-secondary"
5934
6090
  ),
5935
6091
  children: item.title
@@ -5956,7 +6112,7 @@ function CenterRow({
5956
6112
  ] })
5957
6113
  ] });
5958
6114
  }
5959
- var NotificationCenter = React79.forwardRef(
6115
+ var NotificationCenter = React80.forwardRef(
5960
6116
  ({
5961
6117
  items,
5962
6118
  header = true,
@@ -5973,16 +6129,16 @@ var NotificationCenter = React79.forwardRef(
5973
6129
  formatAge,
5974
6130
  className
5975
6131
  }, ref) => {
5976
- const [status, setStatus] = React79.useState("all");
5977
- const [source, setSource] = React79.useState("all");
5978
- const [product, setProduct] = React79.useState("all");
5979
- const [query, setQuery] = React79.useState("");
5980
- const [limit, setLimit] = React79.useState(pageSize);
5981
- const age = React79.useCallback(
6132
+ const [status, setStatus] = React80.useState("all");
6133
+ const [source, setSource] = React80.useState("all");
6134
+ const [product, setProduct] = React80.useState("all");
6135
+ const [query, setQuery] = React80.useState("");
6136
+ const [limit, setLimit] = React80.useState(pageSize);
6137
+ const age = React80.useCallback(
5982
6138
  (createdAt) => formatAge ? formatAge(createdAt) : formatRelativeAge(createdAt),
5983
6139
  [formatAge]
5984
6140
  );
5985
- const sourceChips = React79.useMemo(
6141
+ const sourceChips = React80.useMemo(
5986
6142
  () => sources ?? Array.from(new Set(items.map((n) => n.source))),
5987
6143
  [sources, items]
5988
6144
  );
@@ -6004,13 +6160,13 @@ var NotificationCenter = React79.forwardRef(
6004
6160
  {
6005
6161
  type: "button",
6006
6162
  onClick: () => onMarkAllRead(),
6007
- className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
6163
+ className: "shrink-0 cursor-pointer rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
6008
6164
  children: "Read all"
6009
6165
  }
6010
6166
  )
6011
6167
  ] }),
6012
6168
  searchable && /* @__PURE__ */ jsxs62("div", { className: "mb-3 flex items-center gap-2 rounded-lg bg-bg-elevated px-3 py-2", children: [
6013
- /* @__PURE__ */ jsx94(Search2, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
6169
+ /* @__PURE__ */ jsx94(Search4, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
6014
6170
  /* @__PURE__ */ jsx94(
6015
6171
  "input",
6016
6172
  {
@@ -6101,7 +6257,7 @@ var NotificationCenter = React79.forwardRef(
6101
6257
  {
6102
6258
  type: "button",
6103
6259
  onClick: () => setLimit((l) => l + pageSize),
6104
- className: "mt-1 rounded-lg bg-bg-elevated px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
6260
+ className: "mt-1 cursor-pointer rounded-lg bg-bg-elevated px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
6105
6261
  children: [
6106
6262
  "Load ",
6107
6263
  remaining,
@@ -6116,7 +6272,7 @@ var NotificationCenter = React79.forwardRef(
6116
6272
  NotificationCenter.displayName = "NotificationCenter";
6117
6273
 
6118
6274
  // src/components/notification-settings.tsx
6119
- import * as React80 from "react";
6275
+ import * as React81 from "react";
6120
6276
  import { Moon as Moon2, Plus as Plus3, Volume2 } from "lucide-react";
6121
6277
  import { Fragment as Fragment11, jsx as jsx95, jsxs as jsxs63 } from "react/jsx-runtime";
6122
6278
  var THRESHOLDS = [
@@ -6143,7 +6299,7 @@ function ThresholdControl({
6143
6299
  }
6144
6300
  );
6145
6301
  }
6146
- var NotificationSettings = React80.forwardRef(
6302
+ var NotificationSettings = React81.forwardRef(
6147
6303
  ({
6148
6304
  subscriptions,
6149
6305
  value,
@@ -6156,7 +6312,7 @@ var NotificationSettings = React80.forwardRef(
6156
6312
  pushSlot,
6157
6313
  className
6158
6314
  }, ref) => {
6159
- const [tab, setTab] = React80.useState(DEFAULT_KEY);
6315
+ const [tab, setTab] = React81.useState(DEFAULT_KEY);
6160
6316
  const isDefault = tab === DEFAULT_KEY;
6161
6317
  const defaults = value[DEFAULT_KEY] ?? { thresholds: {} };
6162
6318
  const customized = !isDefault && Object.prototype.hasOwnProperty.call(value, tab);
@@ -6177,7 +6333,7 @@ var NotificationSettings = React80.forwardRef(
6177
6333
  const rows = subscriptions.filter((s) => s.scope === scope);
6178
6334
  if (rows.length === 0) return null;
6179
6335
  return /* @__PURE__ */ jsxs63("div", { children: [
6180
- /* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-bold uppercase tracking-wider text-text-tertiary", children: scope === "product" ? "This product" : "Organization" }),
6336
+ /* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-medium text-text-tertiary", children: scope === "product" ? "This product" : "Organization" }),
6181
6337
  /* @__PURE__ */ jsx95("div", { className: "space-y-2", children: rows.map((sub) => /* @__PURE__ */ jsxs63(
6182
6338
  "div",
6183
6339
  {
@@ -6200,7 +6356,7 @@ var NotificationSettings = React80.forwardRef(
6200
6356
  };
6201
6357
  return /* @__PURE__ */ jsxs63("div", { ref, className: cn("space-y-5", className), children: [
6202
6358
  products && products.length > 0 && /* @__PURE__ */ jsxs63("div", { children: [
6203
- /* @__PURE__ */ jsx95("p", { className: "mb-2 px-0.5 text-xs font-bold uppercase tracking-wider text-text-tertiary", children: "Preferences for" }),
6359
+ /* @__PURE__ */ jsx95("p", { className: "mb-2 px-0.5 text-xs font-medium text-text-tertiary", children: "Preferences for" }),
6204
6360
  /* @__PURE__ */ jsx95(
6205
6361
  ToggleGroup,
6206
6362
  {
@@ -6217,18 +6373,18 @@ var NotificationSettings = React80.forwardRef(
6217
6373
  isDefault ? /* @__PURE__ */ jsxs63(Fragment11, { children: [
6218
6374
  /* @__PURE__ */ jsx95("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." }),
6219
6375
  /* @__PURE__ */ jsxs63(Card, { className: "border-none bg-bg-elevated p-5", children: [
6220
- /* @__PURE__ */ jsx95("p", { className: "mb-1.5 text-xs font-bold uppercase tracking-wide text-text-tertiary", children: "Push to" }),
6376
+ /* @__PURE__ */ jsx95(CardTitle, { as: "p", className: "mb-1.5", children: "Push to" }),
6221
6377
  /* @__PURE__ */ jsx95("p", { className: "mb-3 text-sm leading-relaxed text-text-secondary", children: "Forward notifications beyond the in-app record to a connected integration." }),
6222
6378
  pushSlot ?? /* @__PURE__ */ jsx95("div", { className: "rounded-lg bg-bg-surface px-4 py-6 text-center", children: /* @__PURE__ */ jsx95("p", { className: "text-sm text-text-tertiary", children: "No integrations connected." }) })
6223
6379
  ] }),
6224
6380
  mutes.length > 0 && /* @__PURE__ */ jsxs63("div", { children: [
6225
- /* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-bold uppercase tracking-wider text-text-tertiary", children: "Muted" }),
6381
+ /* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-medium text-text-tertiary", children: "Muted" }),
6226
6382
  /* @__PURE__ */ jsx95(Card, { className: "border-none bg-bg-elevated p-2", children: mutes.map((m) => /* @__PURE__ */ jsxs63("div", { className: "flex items-center gap-3 rounded-lg px-3 py-2.5", children: [
6227
6383
  /* @__PURE__ */ jsx95(Moon2, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
6228
6384
  /* @__PURE__ */ jsxs63("div", { className: "min-w-0 flex-1", children: [
6229
6385
  /* @__PURE__ */ jsx95("p", { className: "text-sm font-medium text-text-primary", children: m.source }),
6230
6386
  /* @__PURE__ */ jsxs63("p", { className: "text-sm text-text-tertiary", children: [
6231
- "Muted \u2014 ",
6387
+ "Muted, ",
6232
6388
  m.label,
6233
6389
  ". Critical still comes through."
6234
6390
  ] })
@@ -6238,7 +6394,7 @@ var NotificationSettings = React80.forwardRef(
6238
6394
  {
6239
6395
  type: "button",
6240
6396
  onClick: () => onUnmute?.(m.source),
6241
- className: "rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
6397
+ className: "cursor-pointer rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
6242
6398
  children: "Unmute"
6243
6399
  }
6244
6400
  )
@@ -6272,7 +6428,7 @@ var NotificationSettings = React80.forwardRef(
6272
6428
  {
6273
6429
  type: "button",
6274
6430
  onClick: customize,
6275
- 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 duration-fast hover:bg-bg-brand-hover",
6431
+ className: "mt-5 inline-flex cursor-pointer 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 duration-fast hover:bg-bg-brand-hover",
6276
6432
  children: [
6277
6433
  /* @__PURE__ */ jsx95(Plus3, { className: "size-4", "aria-hidden": "true" }),
6278
6434
  " Customize for ",
@@ -6294,7 +6450,7 @@ var NotificationSettings = React80.forwardRef(
6294
6450
  {
6295
6451
  type: "button",
6296
6452
  onClick: resetToDefault,
6297
- className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-danger",
6453
+ className: "shrink-0 cursor-pointer rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-danger",
6298
6454
  children: "Reset to Default"
6299
6455
  }
6300
6456
  )
@@ -6307,14 +6463,14 @@ var NotificationSettings = React80.forwardRef(
6307
6463
  NotificationSettings.displayName = "NotificationSettings";
6308
6464
 
6309
6465
  // src/components/notification-toast.tsx
6310
- import * as React81 from "react";
6466
+ import * as React82 from "react";
6311
6467
  import { X as X4 } from "lucide-react";
6312
6468
  import { jsx as jsx96, jsxs as jsxs64 } from "react/jsx-runtime";
6313
- var chipBase2 = "rounded-lg px-2.5 py-1 text-sm font-medium transition-colors duration-fast";
6469
+ var chipBase2 = "cursor-pointer rounded-lg px-2.5 py-1 text-sm font-medium transition-colors duration-fast";
6314
6470
  var chipPrimary = "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover";
6315
6471
  var chipDestructive = "bg-bg-elevated text-text-danger hover:bg-bg-surface";
6316
- var linkAction = "text-sm font-semibold text-text-brand transition-colors duration-fast hover:text-text-primary";
6317
- var NotificationToast = React81.forwardRef(
6472
+ var linkAction = "cursor-pointer text-sm font-semibold text-text-brand transition-colors duration-fast hover:text-text-primary";
6473
+ var NotificationToast = React82.forwardRef(
6318
6474
  ({
6319
6475
  item,
6320
6476
  showSource = true,
@@ -6331,7 +6487,7 @@ var NotificationToast = React81.forwardRef(
6331
6487
  const actions = item.actions ?? [];
6332
6488
  const percent = progress === void 0 || !Number.isFinite(progress) ? void 0 : Math.min(100, Math.max(0, progress));
6333
6489
  const progressLine = progressLabel === void 0 && percent !== void 0 ? `live, ${Math.round(percent)}%` : progressLabel;
6334
- const barId = React81.useId();
6490
+ const barId = React82.useId();
6335
6491
  const hasProgressLine = progressLine !== null && progressLine !== void 0;
6336
6492
  return /* @__PURE__ */ jsxs64(
6337
6493
  "div",
@@ -6345,7 +6501,7 @@ var NotificationToast = React81.forwardRef(
6345
6501
  ),
6346
6502
  children: [
6347
6503
  /* @__PURE__ */ jsxs64("div", { className: "flex items-center gap-2", children: [
6348
- showSource && /* @__PURE__ */ jsx96("span", { className: "text-xs font-semibold uppercase tracking-[0.09em] text-text-secondary", children: item.source }),
6504
+ showSource && /* @__PURE__ */ jsx96("span", { className: "text-xs font-semibold text-text-tertiary", children: item.source }),
6349
6505
  /* @__PURE__ */ jsx96(Badge, { variant: severityBadgeVariant(item.severity), children: severityLabels[item.severity] }),
6350
6506
  (overflow || onDismiss) && /* @__PURE__ */ jsxs64("span", { className: "-mr-1 ml-auto flex shrink-0 items-center gap-1", children: [
6351
6507
  overflow,
@@ -6355,7 +6511,7 @@ var NotificationToast = React81.forwardRef(
6355
6511
  type: "button",
6356
6512
  "aria-label": dismissLabel,
6357
6513
  onClick: () => onDismiss(item),
6358
- className: "flex size-5 shrink-0 items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
6514
+ className: "flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
6359
6515
  children: /* @__PURE__ */ jsx96(X4, { className: "size-3.5", "aria-hidden": "true" })
6360
6516
  }
6361
6517
  )
@@ -6366,7 +6522,7 @@ var NotificationToast = React81.forwardRef(
6366
6522
  {
6367
6523
  type: "button",
6368
6524
  onClick: () => onItemClick(item),
6369
- className: "mt-1 block text-left text-sm font-semibold leading-snug text-text-primary underline-offset-2 hover:underline",
6525
+ className: "mt-1 block cursor-pointer text-left text-sm font-semibold leading-snug text-text-primary underline-offset-2 hover:underline",
6370
6526
  children: item.title
6371
6527
  }
6372
6528
  ) : /* @__PURE__ */ jsx96("p", { className: "mt-1 text-sm font-semibold leading-snug text-text-primary", children: item.title }),
@@ -6409,7 +6565,7 @@ var NotificationToast = React81.forwardRef(
6409
6565
  NotificationToast.displayName = "NotificationToast";
6410
6566
 
6411
6567
  // src/components/notification-toaster.tsx
6412
- import * as React82 from "react";
6568
+ import * as React83 from "react";
6413
6569
  import { jsx as jsx97 } from "react/jsx-runtime";
6414
6570
  var positions = {
6415
6571
  "bottom-right": "bottom-6 right-6 flex-col",
@@ -6417,7 +6573,7 @@ var positions = {
6417
6573
  "top-right": "top-6 right-6 flex-col-reverse",
6418
6574
  "top-left": "top-6 left-6 flex-col-reverse"
6419
6575
  };
6420
- var NotificationToaster = React82.forwardRef(
6576
+ var NotificationToaster = React83.forwardRef(
6421
6577
  ({
6422
6578
  items,
6423
6579
  dwell,
@@ -6434,15 +6590,15 @@ var NotificationToaster = React82.forwardRef(
6434
6590
  className
6435
6591
  }, ref) => {
6436
6592
  const shown = items.slice(0, max);
6437
- const [paused, setPaused] = React82.useState(false);
6438
- const onDismissRef = React82.useRef(onDismiss);
6593
+ const [paused, setPaused] = React83.useState(false);
6594
+ const onDismissRef = React83.useRef(onDismiss);
6439
6595
  onDismissRef.current = onDismiss;
6440
6596
  const fyiDwell = dwell?.fyi;
6441
6597
  const importantDwell = dwell?.important;
6442
6598
  const criticalDwell = dwell?.critical;
6443
- const remaining = React82.useRef(/* @__PURE__ */ new Map());
6599
+ const remaining = React83.useRef(/* @__PURE__ */ new Map());
6444
6600
  const liveIds = shown.map((item) => `${item.id}:${item.severity}`).join(" ");
6445
- React82.useEffect(() => {
6601
+ React83.useEffect(() => {
6446
6602
  const owedById = remaining.current;
6447
6603
  const dwellSeconds = {
6448
6604
  fyi: fyiDwell ?? TOAST_DWELL.fyi,
@@ -6770,7 +6926,7 @@ var COUNTRY_OPTIONS = [
6770
6926
  ];
6771
6927
 
6772
6928
  // src/components/organization-onboarding-form.tsx
6773
- import * as React83 from "react";
6929
+ import * as React84 from "react";
6774
6930
 
6775
6931
  // src/lib/auth-surface.ts
6776
6932
  var AUTH_FILLED_BUTTON = "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 duration-fast 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]";
@@ -6781,10 +6937,20 @@ var AUTH_BUTTON_SHADOW = "var(--auth-btn-shadow)";
6781
6937
  import { jsx as jsx98, jsxs as jsxs65 } from "react/jsx-runtime";
6782
6938
  var CONTROLLER_SHARE_PCT = 50;
6783
6939
  var MAX_BENEFICIAL_OWNERS = 50;
6940
+ var REQUIRED_FIELD_LABELS = {
6941
+ name: "Organization name",
6942
+ legalName: "Legal name",
6943
+ ownerName: "Owner name",
6944
+ countryOfIncorporation: "Country of incorporation",
6945
+ residencyCountry: "Country of residency"
6946
+ };
6784
6947
  var OWNERSHIP_CONFIRMATION_MESSAGE = "Please confirm the ownership details by ticking the box";
6785
6948
  function isOwnershipViolation(violation) {
6786
6949
  return /ownership[_\s-]?confirmed/i.test(violation);
6787
6950
  }
6951
+ function RequiredMark() {
6952
+ return /* @__PURE__ */ jsx98("span", { className: "text-text-danger", children: " *" });
6953
+ }
6788
6954
  function parseShare(raw) {
6789
6955
  if (!/^\d{1,3}$/.test(raw.trim())) return null;
6790
6956
  const n = Number(raw);
@@ -6802,7 +6968,6 @@ function initialRows(owners) {
6802
6968
  }));
6803
6969
  }
6804
6970
  function OrganizationOnboardingForm({
6805
- requireSanctionsFields,
6806
6971
  onSubmit,
6807
6972
  defaultValues,
6808
6973
  submitting,
@@ -6813,22 +6978,23 @@ function OrganizationOnboardingForm({
6813
6978
  onCancel,
6814
6979
  className
6815
6980
  }) {
6816
- const [name, setName] = React83.useState(defaultValues?.name ?? "");
6817
- const [legalName, setLegalName] = React83.useState(defaultValues?.legal_name ?? "");
6818
- const [ownerName, setOwnerName] = React83.useState(defaultValues?.owner_name ?? "");
6819
- const [countryOfIncorporation, setCountryOfIncorporation] = React83.useState(
6981
+ const [name, setName] = React84.useState(defaultValues?.name ?? "");
6982
+ const [legalName, setLegalName] = React84.useState(defaultValues?.legal_name ?? "");
6983
+ const [ownerName, setOwnerName] = React84.useState(defaultValues?.owner_name ?? "");
6984
+ const [countryOfIncorporation, setCountryOfIncorporation] = React84.useState(
6820
6985
  defaultValues?.country_of_incorporation ?? ""
6821
6986
  );
6822
- const [residencyCountry, setResidencyCountry] = React83.useState(
6987
+ const [residencyCountry, setResidencyCountry] = React84.useState(
6823
6988
  defaultValues?.residency_country ?? ""
6824
6989
  );
6825
- const [owners, setOwners] = React83.useState(
6990
+ const [owners, setOwners] = React84.useState(
6826
6991
  () => initialRows(defaultValues?.beneficial_owners)
6827
6992
  );
6828
- const [ownershipConfirmed, setOwnershipConfirmed] = React83.useState(false);
6829
- const [confirmationAttempted, setConfirmationAttempted] = React83.useState(false);
6830
- const nextKeyRef = React83.useRef(owners.length);
6831
- const submittingRef = React83.useRef(false);
6993
+ const [ownershipConfirmed, setOwnershipConfirmed] = React84.useState(false);
6994
+ const [confirmationAttempted, setConfirmationAttempted] = React84.useState(false);
6995
+ const [requiredAttempted, setRequiredAttempted] = React84.useState(false);
6996
+ const nextKeyRef = React84.useRef(owners.length);
6997
+ const submittingRef = React84.useRef(false);
6832
6998
  const trimmed = name.trim();
6833
6999
  const filledOwners = owners.filter((row) => !isRowBlank(row));
6834
7000
  const ownerShares = filledOwners.map((row) => parseShare(row.share));
@@ -6840,9 +7006,16 @@ function OrganizationOnboardingForm({
6840
7006
  (share) => share !== null && share >= CONTROLLER_SHARE_PCT
6841
7007
  );
6842
7008
  const needsOwnershipConfirmation = !hasController;
6843
- const missingCountry = requireSanctionsFields && countryOfIncorporation === "";
7009
+ const missingRequired = [
7010
+ [trimmed, REQUIRED_FIELD_LABELS.name],
7011
+ [legalName.trim(), REQUIRED_FIELD_LABELS.legalName],
7012
+ [ownerName.trim(), REQUIRED_FIELD_LABELS.ownerName],
7013
+ [countryOfIncorporation, REQUIRED_FIELD_LABELS.countryOfIncorporation],
7014
+ [residencyCountry, REQUIRED_FIELD_LABELS.residencyCountry]
7015
+ ].filter(([value]) => value === "").map(([, label]) => label);
6844
7016
  const missingConfirmation = needsOwnershipConfirmation && !ownershipConfirmed;
6845
- const canSubmit = trimmed !== "" && ownersValid && !missingCountry && !submitting;
7017
+ const canSubmit = ownersValid && !submitting;
7018
+ const showRequiredError = requiredAttempted && missingRequired.length > 0;
6846
7019
  const ownershipViolations = needsOwnershipConfirmation ? (violations ?? []).filter(isOwnershipViolation) : [];
6847
7020
  const otherViolations = (violations ?? []).filter(
6848
7021
  (violation) => !ownershipViolations.includes(violation)
@@ -6861,7 +7034,8 @@ function OrganizationOnboardingForm({
6861
7034
  const handleSubmit = (event) => {
6862
7035
  event.preventDefault();
6863
7036
  if (!canSubmit || submittingRef.current) return;
6864
- if (missingConfirmation) {
7037
+ if (missingRequired.length > 0 || missingConfirmation) {
7038
+ setRequiredAttempted(true);
6865
7039
  setConfirmationAttempted(true);
6866
7040
  return;
6867
7041
  }
@@ -6873,16 +7047,16 @@ function OrganizationOnboardingForm({
6873
7047
  }));
6874
7048
  onSubmit({
6875
7049
  name: trimmed,
6876
- ...legalName.trim() !== "" ? { legal_name: legalName.trim() } : {},
6877
- ...ownerName.trim() !== "" ? { owner_name: ownerName.trim() } : {},
6878
- ...countryOfIncorporation !== "" ? { country_of_incorporation: countryOfIncorporation } : {},
6879
- ...residencyCountry !== "" ? { residency_country: residencyCountry } : {},
7050
+ legal_name: legalName.trim(),
7051
+ owner_name: ownerName.trim(),
7052
+ country_of_incorporation: countryOfIncorporation,
7053
+ residency_country: residencyCountry,
6880
7054
  beneficial_owners: beneficialOwners,
6881
7055
  // Only meaningful — and only collected — when the list shows no controlling owner.
6882
7056
  ...needsOwnershipConfirmation ? { ownership_confirmed: ownershipConfirmed } : {}
6883
7057
  });
6884
7058
  };
6885
- React83.useEffect(() => {
7059
+ React84.useEffect(() => {
6886
7060
  submittingRef.current = false;
6887
7061
  }, [
6888
7062
  name,
@@ -6898,7 +7072,7 @@ function OrganizationOnboardingForm({
6898
7072
  const countryField = (params) => /* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
6899
7073
  /* @__PURE__ */ jsxs65(Label2, { htmlFor: params.id, children: [
6900
7074
  params.label,
6901
- params.required && /* @__PURE__ */ jsx98("span", { className: "text-text-danger", children: " *" })
7075
+ /* @__PURE__ */ jsx98(RequiredMark, {})
6902
7076
  ] }),
6903
7077
  /* @__PURE__ */ jsx98(
6904
7078
  Select,
@@ -6915,7 +7089,10 @@ function OrganizationOnboardingForm({
6915
7089
  ] });
6916
7090
  return /* @__PURE__ */ jsxs65("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
6917
7091
  /* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
6918
- /* @__PURE__ */ jsx98(Label2, { htmlFor: "create-org-name", children: "Organization name" }),
7092
+ /* @__PURE__ */ jsxs65(Label2, { htmlFor: "create-org-name", children: [
7093
+ REQUIRED_FIELD_LABELS.name,
7094
+ /* @__PURE__ */ jsx98(RequiredMark, {})
7095
+ ] }),
6919
7096
  /* @__PURE__ */ jsx98(
6920
7097
  Input,
6921
7098
  {
@@ -6928,7 +7105,10 @@ function OrganizationOnboardingForm({
6928
7105
  )
6929
7106
  ] }),
6930
7107
  /* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
6931
- /* @__PURE__ */ jsx98(Label2, { htmlFor: "create-org-legal-name", children: "Legal name" }),
7108
+ /* @__PURE__ */ jsxs65(Label2, { htmlFor: "create-org-legal-name", children: [
7109
+ REQUIRED_FIELD_LABELS.legalName,
7110
+ /* @__PURE__ */ jsx98(RequiredMark, {})
7111
+ ] }),
6932
7112
  /* @__PURE__ */ jsx98(
6933
7113
  Input,
6934
7114
  {
@@ -6941,7 +7121,10 @@ function OrganizationOnboardingForm({
6941
7121
  )
6942
7122
  ] }),
6943
7123
  /* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
6944
- /* @__PURE__ */ jsx98(Label2, { htmlFor: "create-org-owner-name", children: "Owner name" }),
7124
+ /* @__PURE__ */ jsxs65(Label2, { htmlFor: "create-org-owner-name", children: [
7125
+ REQUIRED_FIELD_LABELS.ownerName,
7126
+ /* @__PURE__ */ jsx98(RequiredMark, {})
7127
+ ] }),
6945
7128
  /* @__PURE__ */ jsx98(
6946
7129
  Input,
6947
7130
  {
@@ -6955,17 +7138,15 @@ function OrganizationOnboardingForm({
6955
7138
  ] }),
6956
7139
  countryField({
6957
7140
  id: "create-org-country",
6958
- label: "Country of incorporation",
7141
+ label: REQUIRED_FIELD_LABELS.countryOfIncorporation,
6959
7142
  value: countryOfIncorporation,
6960
- onChange: setCountryOfIncorporation,
6961
- required: requireSanctionsFields
7143
+ onChange: setCountryOfIncorporation
6962
7144
  }),
6963
7145
  countryField({
6964
7146
  id: "create-org-residency",
6965
- label: "Country of residency",
7147
+ label: REQUIRED_FIELD_LABELS.residencyCountry,
6966
7148
  value: residencyCountry,
6967
- onChange: setResidencyCountry,
6968
- required: false
7149
+ onChange: setResidencyCountry
6969
7150
  }),
6970
7151
  /* @__PURE__ */ jsxs65("div", { className: "space-y-2", children: [
6971
7152
  /* @__PURE__ */ jsxs65("div", { className: "flex items-center justify-between", children: [
@@ -7071,7 +7252,7 @@ function OrganizationOnboardingForm({
7071
7252
  className: "text-xs font-regular leading-snug",
7072
7253
  children: [
7073
7254
  "I confirm the ownership structure above is complete and correct",
7074
- /* @__PURE__ */ jsx98("span", { className: "text-text-danger", children: " *" })
7255
+ /* @__PURE__ */ jsx98(RequiredMark, {})
7075
7256
  ]
7076
7257
  }
7077
7258
  )
@@ -7086,7 +7267,8 @@ function OrganizationOnboardingForm({
7086
7267
  }
7087
7268
  )
7088
7269
  ] }),
7089
- (serverError || otherViolations.length > 0) && /* @__PURE__ */ jsxs65(InlineError, { children: [
7270
+ showRequiredError && /* @__PURE__ */ jsx98(InlineError, { "data-testid": "create-org-required-error", children: missingRequired.length === 1 ? `${missingRequired[0]} is required` : `These fields are required: ${missingRequired.join(", ")}` }),
7271
+ (serverError || otherViolations.length > 0) && /* @__PURE__ */ jsxs65(InlineError, { "data-testid": "create-org-server-error", children: [
7090
7272
  serverError,
7091
7273
  otherViolations.length > 0 && /* @__PURE__ */ jsx98("ul", { "data-testid": "create-org-violations", className: "mt-1 list-disc pl-4", children: otherViolations.map((violation) => /* @__PURE__ */ jsx98("li", { children: violation }, violation)) })
7092
7274
  ] }),
@@ -7097,18 +7279,18 @@ function OrganizationOnboardingForm({
7097
7279
  type: "submit",
7098
7280
  "data-testid": "submit-create-org",
7099
7281
  disabled: !canSubmit,
7100
- className: AUTH_FILLED_BUTTON,
7282
+ className: cn("cursor-pointer", AUTH_FILLED_BUTTON),
7101
7283
  style: { boxShadow: AUTH_BUTTON_SHADOW },
7102
7284
  children: submitting ? "Creating\u2026" : submitLabel
7103
7285
  }
7104
7286
  ),
7105
- onCancel && /* @__PURE__ */ jsx98("button", { type: "button", onClick: onCancel, className: AUTH_QUIET_BUTTON, children: "Cancel" })
7287
+ onCancel && /* @__PURE__ */ jsx98("button", { type: "button", onClick: onCancel, className: cn("cursor-pointer", AUTH_QUIET_BUTTON), children: "Cancel" })
7106
7288
  ] })
7107
7289
  ] });
7108
7290
  }
7109
7291
 
7110
7292
  // src/components/list-columns.tsx
7111
- import * as React84 from "react";
7293
+ import * as React85 from "react";
7112
7294
  import { jsx as jsx99, jsxs as jsxs66 } from "react/jsx-runtime";
7113
7295
  var CELL_WIDTH = { 20: "w-20", 24: "w-24", 28: "w-28", 32: "w-32" };
7114
7296
  var headerClass = "flex items-center gap-3 border-b border-border-subtle bg-bg-secondary px-4 py-1.5 text-xs text-text-tertiary";
@@ -7127,7 +7309,7 @@ function warnDuplicateKeys(columns, where) {
7127
7309
  seen.add(c.key);
7128
7310
  }
7129
7311
  }
7130
- var ListHeader = React84.forwardRef(function ListHeader2({ lead, columns, mark = true, trailing = true, className, ...props }, ref) {
7312
+ var ListHeader = React85.forwardRef(function ListHeader2({ lead, columns, mark = true, trailing = true, className, ...props }, ref) {
7131
7313
  warnDuplicateKeys(columns, "ListHeader");
7132
7314
  return /* @__PURE__ */ jsxs66("div", { ref, className: cn(headerClass, className), ...props, children: [
7133
7315
  mark && /* @__PURE__ */ jsx99("span", { className: "size-8 shrink-0", "aria-hidden": true }),
@@ -7141,7 +7323,7 @@ function cellValue(values, column) {
7141
7323
  const value = values[column.key];
7142
7324
  return value === void 0 || value === null || value === "" ? column.fallback : value;
7143
7325
  }
7144
- var ListCells = React84.forwardRef(function ListCells2({ columns, values, className, ...props }, ref) {
7326
+ var ListCells = React85.forwardRef(function ListCells2({ columns, values, className, ...props }, ref) {
7145
7327
  warnDuplicateKeys(columns, "ListCells");
7146
7328
  return /* @__PURE__ */ jsx99("span", { ref, className: cn(cellsClass, className), ...props, children: columns.map((c) => /* @__PURE__ */ jsx99(
7147
7329
  "span",
@@ -7156,8 +7338,8 @@ ListHeader.displayName = "ListHeader";
7156
7338
  ListCells.displayName = "ListCells";
7157
7339
 
7158
7340
  // src/components/theme-picker.tsx
7159
- import * as React85 from "react";
7160
- import { Check as Check12, Monitor } from "lucide-react";
7341
+ import * as React86 from "react";
7342
+ import { Check as Check12 } from "lucide-react";
7161
7343
  import { jsx as jsx100, jsxs as jsxs67 } from "react/jsx-runtime";
7162
7344
  var THEME_SWATCHES = {
7163
7345
  // --bg-surface --bg-sunken --bg-overlay --border-default --text-tertiary
@@ -7205,11 +7387,17 @@ function Panels({ palette }) {
7205
7387
  )
7206
7388
  ] });
7207
7389
  }
7208
- var autoPlateClass = "flex h-full items-center justify-center bg-bg-surface";
7390
+ var CUT = "polygon(0 0, -8px 0, -8px calc(100% + 8px), calc(100% + 8px) calc(100% + 8px), calc(100% + 8px) calc(100% - 16px), 100% calc(100% - 16px))";
7391
+ function AutoPanels() {
7392
+ return /* @__PURE__ */ jsxs67("span", { className: "relative block h-full", children: [
7393
+ /* @__PURE__ */ jsx100("span", { className: "absolute inset-0", children: /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES.light }) }),
7394
+ /* @__PURE__ */ jsx100("span", { className: "absolute inset-0", style: { clipPath: CUT }, children: /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES.dark }) })
7395
+ ] });
7396
+ }
7209
7397
  var previewClass = "block h-28 overflow-hidden rounded-lg border border-border-default";
7210
- var cardClass = "grid gap-2 rounded-lg p-1.5 text-left transition-colors duration-fast hover:bg-bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus";
7398
+ var cardClass = "grid cursor-pointer gap-2 rounded-lg p-1.5 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus";
7211
7399
  var TRACK = { gridTemplateColumns: "repeat(auto-fit, minmax(8rem, 1fr))" };
7212
- var Picker = React85.forwardRef(function Picker2({ value, onValueChange, className, ...props }, ref) {
7400
+ var Picker = React86.forwardRef(function Picker2({ value, onValueChange, className, ...props }, ref) {
7213
7401
  return /* @__PURE__ */ jsx100("div", { role: "group", "aria-label": "Theme", ...props, ref, className: cn("grid gap-4", className), style: { ...TRACK, ...props.style }, children: OPTIONS.map((o) => {
7214
7402
  const selected = o.value === value;
7215
7403
  return (
@@ -7224,7 +7412,7 @@ var Picker = React85.forwardRef(function Picker2({ value, onValueChange, classNa
7224
7412
  onClick: () => onValueChange(o.value),
7225
7413
  className: cardClass,
7226
7414
  children: [
7227
- /* @__PURE__ */ jsx100("span", { className: cn(previewClass, selected && "border-border-strong"), "aria-hidden": true, children: o.value === "system" ? /* @__PURE__ */ jsx100("span", { className: autoPlateClass, children: /* @__PURE__ */ jsx100(Monitor, { className: "size-8 text-text-tertiary" }) }) : /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES[o.value] }) }),
7415
+ /* @__PURE__ */ jsx100("span", { className: cn(previewClass, selected && "border-border-strong"), "aria-hidden": true, children: o.value === "system" ? /* @__PURE__ */ jsx100(AutoPanels, {}) : /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES[o.value] }) }),
7228
7416
  /* @__PURE__ */ jsxs67(
7229
7417
  "span",
7230
7418
  {
@@ -7245,7 +7433,7 @@ var Picker = React85.forwardRef(function Picker2({ value, onValueChange, classNa
7245
7433
  );
7246
7434
  }) });
7247
7435
  });
7248
- var WiredPicker = React85.forwardRef(function WiredPicker2({ onValueChange, ...props }, ref) {
7436
+ var WiredPicker = React86.forwardRef(function WiredPicker2({ onValueChange, ...props }, ref) {
7249
7437
  const { theme, setTheme } = useTheme();
7250
7438
  return /* @__PURE__ */ jsx100(
7251
7439
  Picker,
@@ -7260,8 +7448,8 @@ var WiredPicker = React85.forwardRef(function WiredPicker2({ onValueChange, ...p
7260
7448
  }
7261
7449
  );
7262
7450
  });
7263
- var ThemePicker = React85.forwardRef(function ThemePicker2({ value, onValueChange, ...props }, ref) {
7264
- const controlled = React85.useRef(value !== void 0);
7451
+ var ThemePicker = React86.forwardRef(function ThemePicker2({ value, onValueChange, ...props }, ref) {
7452
+ const controlled = React86.useRef(value !== void 0);
7265
7453
  if (process.env.NODE_ENV !== "production" && controlled.current !== (value !== void 0)) {
7266
7454
  console.warn(
7267
7455
  "[ThemePicker] `value` went from " + (controlled.current ? "set to missing" : "missing to set") + " after mount. The picker stays " + (controlled.current ? "controlled" : "wired to the console theme") + " for its whole life: render it once its value is known, or leave `value` off entirely."
@@ -7273,7 +7461,7 @@ var ThemePicker = React85.forwardRef(function ThemePicker2({ value, onValueChang
7273
7461
  ThemePicker.displayName = "ThemePicker";
7274
7462
 
7275
7463
  // src/components/secret-reveal.tsx
7276
- import * as React86 from "react";
7464
+ import * as React87 from "react";
7277
7465
  import { Copy as Copy2, Download } from "lucide-react";
7278
7466
  import { jsx as jsx101, jsxs as jsxs68 } from "react/jsx-runtime";
7279
7467
  var asText = (value) => Array.isArray(value) ? value.join("\n") : value;
@@ -7291,7 +7479,7 @@ function SecretValue({ value }) {
7291
7479
  }
7292
7480
  return /* @__PURE__ */ jsx101("code", { className: "block break-all font-mono text-sm font-medium text-text-primary", children: value });
7293
7481
  }
7294
- var SecretReveal = React86.forwardRef(
7482
+ var SecretReveal = React87.forwardRef(
7295
7483
  ({
7296
7484
  value,
7297
7485
  caption,
@@ -7308,18 +7496,18 @@ var SecretReveal = React86.forwardRef(
7308
7496
  className,
7309
7497
  ...props
7310
7498
  }, ref) => {
7311
- const [takenText, setTakenText] = React86.useState(null);
7312
- const [refusedText, setRefusedText] = React86.useState(null);
7313
- const [announcedFor, setAnnouncedFor] = React86.useState(null);
7314
- const copyRef = React86.useRef(null);
7315
- const captionId = React86.useId();
7499
+ const [takenText, setTakenText] = React87.useState(null);
7500
+ const [refusedText, setRefusedText] = React87.useState(null);
7501
+ const [announcedFor, setAnnouncedFor] = React87.useState(null);
7502
+ const copyRef = React87.useRef(null);
7503
+ const captionId = React87.useId();
7316
7504
  const text = asText(value);
7317
7505
  const empty = text.length === 0;
7318
7506
  const taken = takenText === text;
7319
7507
  const refused = refusedText === text;
7320
- React86.useEffect(() => setAnnouncedFor(text), [text]);
7508
+ React87.useEffect(() => setAnnouncedFor(text), [text]);
7321
7509
  const announced = announcedFor === text ? REVEALED : "";
7322
- React86.useEffect(() => {
7510
+ React87.useEffect(() => {
7323
7511
  if (autoFocus) copyRef.current?.focus();
7324
7512
  }, [autoFocus]);
7325
7513
  const reportTaken = () => {
@@ -7381,7 +7569,7 @@ var SecretReveal = React86.forwardRef(
7381
7569
  SecretReveal.displayName = "SecretReveal";
7382
7570
 
7383
7571
  // src/components/star-rating.tsx
7384
- import * as React87 from "react";
7572
+ import * as React88 from "react";
7385
7573
  import * as RadioGroupPrimitive2 from "@radix-ui/react-radio-group";
7386
7574
  import { Star } from "lucide-react";
7387
7575
  import { jsx as jsx102 } from "react/jsx-runtime";
@@ -7407,7 +7595,7 @@ var StarGlyph = ({ filled, size }) => /* @__PURE__ */ jsx102(
7407
7595
  )
7408
7596
  }
7409
7597
  );
7410
- var StarRating = React87.forwardRef(
7598
+ var StarRating = React88.forwardRef(
7411
7599
  ({
7412
7600
  className,
7413
7601
  value,
@@ -7422,9 +7610,9 @@ var StarRating = React87.forwardRef(
7422
7610
  ...props
7423
7611
  }, ref) => {
7424
7612
  const stars = Array.from({ length: max }, (_, index) => index + 1);
7425
- const [mirror, setMirror] = React87.useState(defaultValue ?? 0);
7613
+ const [mirror, setMirror] = React88.useState(defaultValue ?? 0);
7426
7614
  const selected = value ?? mirror;
7427
- const [preview, setPreview] = React87.useState(null);
7615
+ const [preview, setPreview] = React88.useState(null);
7428
7616
  const shown = preview ?? selected;
7429
7617
  const commit = (next) => {
7430
7618
  setMirror(next);
@@ -7470,6 +7658,7 @@ var StarRating = React87.forwardRef(
7470
7658
  if (min === 0 && star === selected) commit(0);
7471
7659
  },
7472
7660
  className: cn(
7661
+ "cursor-pointer",
7473
7662
  // Focus is an outline held off the box, never a flush ring (`Guidelines/Look/Borders`).
7474
7663
  "rounded-md p-0.5 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
7475
7664
  "disabled:pointer-events-none disabled:opacity-50"
@@ -7485,7 +7674,7 @@ var StarRating = React87.forwardRef(
7485
7674
  StarRating.displayName = "StarRating";
7486
7675
 
7487
7676
  // src/components/rating-scale.tsx
7488
- import * as React88 from "react";
7677
+ import * as React89 from "react";
7489
7678
  import * as RadioGroupPrimitive3 from "@radix-ui/react-radio-group";
7490
7679
  import { jsx as jsx103, jsxs as jsxs69 } from "react/jsx-runtime";
7491
7680
  var SLOT_BOX = {
@@ -7494,7 +7683,7 @@ var SLOT_BOX = {
7494
7683
  lg: "h-11 min-w-11 px-3 text-base"
7495
7684
  };
7496
7685
  var defaultItemLabel2 = (value, _min, max) => `${value} out of ${max}`;
7497
- var RatingScale = React88.forwardRef(
7686
+ var RatingScale = React89.forwardRef(
7498
7687
  ({
7499
7688
  className,
7500
7689
  value,
@@ -7510,7 +7699,7 @@ var RatingScale = React88.forwardRef(
7510
7699
  ...props
7511
7700
  }, ref) => {
7512
7701
  const slots = Array.from({ length: Math.max(0, max - min + 1) }, (_, index) => min + index);
7513
- const [mirror, setMirror] = React88.useState(defaultValue);
7702
+ const [mirror, setMirror] = React89.useState(defaultValue);
7514
7703
  const selected = value ?? mirror;
7515
7704
  const row = /* @__PURE__ */ jsx103("div", { className: cn("flex flex-wrap items-center gap-1.5", !endLabels && className), children: slots.map((slot) => {
7516
7705
  const isSelected = slot === selected;
@@ -7529,6 +7718,7 @@ var RatingScale = React88.forwardRef(
7529
7718
  "aria-label": itemLabel(slot, min, max),
7530
7719
  className: cn(
7531
7720
  box,
7721
+ "cursor-pointer",
7532
7722
  // The hover step is the same channel the mark uses, one rung short of it, so the
7533
7723
  // pointer never promises a mark it is not making.
7534
7724
  "hover:border-field-border-hover hover:text-text-primary",
@@ -7797,8 +7987,10 @@ export {
7797
7987
  PopoverContent,
7798
7988
  PopoverTrigger,
7799
7989
  Progress,
7990
+ QuickSearchRow,
7800
7991
  RadioGroup2 as RadioGroup,
7801
7992
  RadioGroupItem,
7993
+ RailToggle,
7802
7994
  RatingScale,
7803
7995
  RemovableChip,
7804
7996
  RemoveButton,
@@ -7867,6 +8059,7 @@ export {
7867
8059
  isKnownExtensionIcon,
7868
8060
  isNotificationSettled,
7869
8061
  navigationMenuTriggerStyle,
8062
+ productStatusBadge,
7870
8063
  severityBadgeVariant,
7871
8064
  severityLabels,
7872
8065
  statusDotVariants,