@lessly/ui 2.2.0 → 2.3.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
@@ -19,7 +19,7 @@ import {
19
19
  cn,
20
20
  useIsMobile,
21
21
  useSidebar
22
- } from "./chunk-F5RMHSPS.js";
22
+ } from "./chunk-CEXND5YW.js";
23
23
 
24
24
  // src/components/auto-height.tsx
25
25
  import * as React from "react";
@@ -170,7 +170,7 @@ var DialogContent = React3.forwardRef(({ className, children, showClose = true,
170
170
  ...props,
171
171
  children: [
172
172
  children,
173
- showClose && /* @__PURE__ */ jsxs2(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm text-text-tertiary opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-border-focus disabled:pointer-events-none", 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: [
174
174
  /* @__PURE__ */ jsx3(X, { className: "h-4 w-4" }),
175
175
  /* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
176
176
  ] })
@@ -291,7 +291,7 @@ var DropdownMenuItem = React4.forwardRef(({ className, inset, variant = "default
291
291
  {
292
292
  ref,
293
293
  className: cn(
294
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
294
+ "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
295
  inset && "pl-8",
296
296
  // Destructive reddens — wash and label — under the pointer or the keyboard, and drops the red
297
297
  // frame a destructive Button rests on, because a row repeated down a menu makes the whole menu
@@ -308,7 +308,7 @@ var DropdownMenuCheckboxItem = React4.forwardRef(({ className, children, checked
308
308
  {
309
309
  ref,
310
310
  className: cn(
311
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset focus:ring-border-selected data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
311
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset focus:ring-border-selected data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
312
312
  className
313
313
  ),
314
314
  checked,
@@ -325,7 +325,7 @@ var DropdownMenuRadioItem = React4.forwardRef(({ className, children, ...props }
325
325
  {
326
326
  ref,
327
327
  className: cn(
328
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset focus:ring-border-selected data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
328
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset focus:ring-border-selected data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
329
329
  className
330
330
  ),
331
331
  ...props,
@@ -349,7 +349,7 @@ var DropdownMenuSeparator = React4.forwardRef(({ className, ...props }, ref) =>
349
349
  DropdownMenuPrimitive.Separator,
350
350
  {
351
351
  ref,
352
- className: cn("-mx-1 my-1 h-px bg-border-default", className),
352
+ className: cn("-mx-1 my-1 h-px bg-border-subtle", className),
353
353
  ...props
354
354
  }
355
355
  ));
@@ -479,7 +479,7 @@ import { cva as cva2 } from "class-variance-authority";
479
479
  import { Check as Check2 } from "lucide-react";
480
480
  import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
481
481
  var optionCardVariants = cva2(
482
- "flex w-full items-center gap-3 rounded-lg border border-border-default p-3 text-left transition-colors hover:bg-bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
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",
483
483
  {
484
484
  variants: {
485
485
  selected: {
@@ -724,18 +724,18 @@ function Switch({
724
724
  "data-testid": testId,
725
725
  disabled,
726
726
  onClick: () => onCheckedChange(!checked),
727
- className: `relative inline-flex h-6 w-10 shrink-0 cursor-pointer rounded-full transition-colors 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}`,
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}`,
728
728
  children: [
729
729
  /* @__PURE__ */ jsx14(
730
730
  "span",
731
731
  {
732
- className: `pointer-events-none absolute inset-0 rounded-full border border-border-strong transition-opacity ${checked ? "opacity-0" : "opacity-100"}`
732
+ className: `pointer-events-none absolute inset-0 rounded-full border border-border-strong transition-opacity duration-fast ${checked ? "opacity-0" : "opacity-100"}`
733
733
  }
734
734
  ),
735
735
  /* @__PURE__ */ jsx14(
736
736
  "span",
737
737
  {
738
- className: `pointer-events-none absolute inset-y-0 left-0 flex w-6 items-center justify-center transition-opacity ${checked ? "opacity-100" : "opacity-0"}`,
738
+ className: `pointer-events-none absolute inset-y-0 left-0 flex w-6 items-center justify-center transition-opacity duration-fast ${checked ? "opacity-100" : "opacity-0"}`,
739
739
  children: /* @__PURE__ */ jsx14(Check3, { className: "size-3 text-white" })
740
740
  }
741
741
  ),
@@ -743,7 +743,7 @@ function Switch({
743
743
  "span",
744
744
  {
745
745
  "aria-hidden": "true",
746
- className: `pointer-events-none absolute top-1/2 left-0 h-4 w-4 -translate-y-1/2 rounded-full transition-transform ${checked ? "translate-x-5 bg-white" : "translate-x-1 bg-border-strong"}`
746
+ className: `pointer-events-none absolute top-1/2 left-0 h-4 w-4 -translate-y-1/2 rounded-full transition-transform duration-fast ${checked ? "translate-x-5 bg-white" : "translate-x-1 bg-border-strong"}`
747
747
  }
748
748
  )
749
749
  ]
@@ -832,7 +832,7 @@ var Slider = React14.forwardRef(({ className, ...props }, ref) => {
832
832
  Array.from({ length: thumbCount }).map((_, i) => /* @__PURE__ */ jsx18(
833
833
  SliderPrimitive.Thumb,
834
834
  {
835
- className: "block size-5 rounded-full border border-border-brand bg-bg-elevated shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
835
+ className: "block size-5 rounded-full border border-border-brand bg-bg-elevated shadow-sm transition-colors duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
836
836
  },
837
837
  i
838
838
  ))
@@ -848,7 +848,7 @@ import * as TogglePrimitive from "@radix-ui/react-toggle";
848
848
  import { cva as cva3 } from "class-variance-authority";
849
849
  import { jsx as jsx19 } from "react/jsx-runtime";
850
850
  var toggleVariants = cva3(
851
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium text-text-secondary transition-colors 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",
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",
852
852
  {
853
853
  variants: {
854
854
  /**
@@ -857,7 +857,7 @@ var toggleVariants = cva3(
857
857
  */
858
858
  treatment: {
859
859
  frame: "ring-1 ring-inset ring-border-subtle hover:bg-bg-secondary hover:text-text-primary data-[state=on]:text-text-primary data-[state=on]:ring-border-strong",
860
- track: "data-[state=off]:hover:text-text-primary data-[state=on]:bg-bg-brand-subtle data-[state=on]:text-text-brand"
860
+ track: "data-[state=off]:hover:text-text-primary data-[state=on]:bg-bg-sunken data-[state=on]:text-text-primary"
861
861
  },
862
862
  variant: {
863
863
  default: "bg-transparent",
@@ -909,7 +909,7 @@ var SlidingThumb = ({ index, count }) => /* @__PURE__ */ jsx20(
909
909
  "span",
910
910
  {
911
911
  "aria-hidden": "true",
912
- className: "motion-segment-thumb pointer-events-none absolute inset-y-0 left-0 rounded-md bg-bg-brand-subtle",
912
+ className: "motion-segment-thumb pointer-events-none absolute inset-y-0 left-0 rounded-md bg-bg-sunken",
913
913
  style: { width: `calc(100% / ${count})`, transform: `translateX(${index * 100}%)` }
914
914
  }
915
915
  );
@@ -945,7 +945,7 @@ var ToggleGroup = React16.forwardRef(({ className, variant, size, treatment, sli
945
945
  // travels in multiples of itself. The gap goes for the same reason: a gap between slots is
946
946
  // width the thumb's own step does not account for. The track sizes to those slots rather
947
947
  // than to whatever holds it — given a parent and no width of its own it used to span the
948
- // whole of it, and with no frame drawn the slots then read as loose words with a tint
948
+ // whole of it, and with no frame drawn the slots then read as loose words with a step
949
949
  // somewhere in them (#754). A caller wanting full width writes one, as every call site did.
950
950
  sliding && "relative flex w-fit gap-0",
951
951
  className
@@ -972,11 +972,11 @@ var ToggleGroupItem = React16.forwardRef(({ className, children, variant, size,
972
972
  // the height its size declares. A slot is the one place this matters most — the items of a
973
973
  // group sit side by side, so one that is 8px wider than its neighbours is visible.
974
974
  isIconOnly(children) && ICON_ONLY_BOX,
975
- // Inside a track, the selected slot is also the heavier word: weight is the one channel that
976
- // survives hue removal, and the tint under it is 1.104:1 light / 1.144:1 dark on its own.
975
+ // Inside a track, the selected slot is also the heavier word: the surface step under it is
976
+ // 1.208:1 light / 1.109:1 dark on its own, which is a mark but not one on its own.
977
977
  context.treatment === "track" && "data-[state=on]:font-semibold",
978
- // Under a sliding thumb the tint belongs to the thumb, which is the one that travels; a second
979
- // copy on the slot would sit still while the first one moved. The word stays the slot's own.
978
+ // Under a sliding thumb the surface step belongs to the thumb, which is the one that travels; a
979
+ // second copy on the slot would sit still while the first one moved. The word stays the slot's own.
980
980
  context.sliding && "relative z-10 flex-1 data-[state=on]:bg-transparent"
981
981
  );
982
982
  if (inert) {
@@ -1016,7 +1016,7 @@ var InputOTPSlot = React17.forwardRef(({ index, className, ...props }, ref) => {
1016
1016
  {
1017
1017
  ref,
1018
1018
  className: cn(
1019
- "relative flex size-10 items-center justify-center border-y border-r text-sm text-text-primary transition-all first:rounded-l-md first:border-l last:rounded-r-md",
1019
+ "relative flex size-10 items-center justify-center border-y border-r text-sm text-text-primary transition-all duration-fast first:rounded-l-md first:border-l last:rounded-r-md",
1020
1020
  // A field takes the field border (`Guidelines/Look/Borders`, #417), and a slot is the other
1021
1021
  // control that can honestly paint the filled step — it holds its own character, so the step
1022
1022
  // is a literal class picked by a boolean and the code walks the ladder as you type.
@@ -1294,7 +1294,7 @@ var ContextMenuItem = React22.forwardRef(({ className, inset, ...props }, ref) =
1294
1294
  {
1295
1295
  ref,
1296
1296
  className: cn(
1297
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1297
+ "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 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1298
1298
  inset && "pl-8",
1299
1299
  className
1300
1300
  ),
@@ -1307,7 +1307,7 @@ var ContextMenuCheckboxItem = React22.forwardRef(({ className, children, checked
1307
1307
  {
1308
1308
  ref,
1309
1309
  className: cn(
1310
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1310
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1311
1311
  className
1312
1312
  ),
1313
1313
  checked,
@@ -1324,7 +1324,7 @@ var ContextMenuRadioItem = React22.forwardRef(({ className, children, ...props }
1324
1324
  {
1325
1325
  ref,
1326
1326
  className: cn(
1327
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1327
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1328
1328
  className
1329
1329
  ),
1330
1330
  ...props,
@@ -1442,7 +1442,7 @@ var MenubarItem = React23.forwardRef(({ className, inset, ...props }, ref) => /*
1442
1442
  {
1443
1443
  ref,
1444
1444
  className: cn(
1445
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1445
+ "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 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1446
1446
  inset && "pl-8",
1447
1447
  className
1448
1448
  ),
@@ -1455,7 +1455,7 @@ var MenubarCheckboxItem = React23.forwardRef(({ className, children, checked, ..
1455
1455
  {
1456
1456
  ref,
1457
1457
  className: cn(
1458
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1458
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1459
1459
  className
1460
1460
  ),
1461
1461
  checked,
@@ -1472,7 +1472,7 @@ var MenubarRadioItem = React23.forwardRef(({ className, children, ...props }, re
1472
1472
  {
1473
1473
  ref,
1474
1474
  className: cn(
1475
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1475
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1476
1476
  className
1477
1477
  ),
1478
1478
  ...props,
@@ -1511,7 +1511,7 @@ import * as React24 from "react";
1511
1511
  import { cva as cva4 } from "class-variance-authority";
1512
1512
  import { jsx as jsx28 } from "react/jsx-runtime";
1513
1513
  var badgeVariants = cva4(
1514
- "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
1514
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
1515
1515
  {
1516
1516
  variants: {
1517
1517
  variant: {
@@ -1571,7 +1571,7 @@ var TableRow = React25.forwardRef(
1571
1571
  {
1572
1572
  ref,
1573
1573
  className: cn(
1574
- "border-b border-border-subtle transition-colors hover:bg-bg-secondary-a50 data-[state=selected]:bg-bg-secondary",
1574
+ "border-b border-border-subtle transition-colors duration-fast hover:bg-bg-secondary-a50 data-[state=selected]:bg-bg-secondary",
1575
1575
  className
1576
1576
  ),
1577
1577
  ...props
@@ -1663,12 +1663,11 @@ var GLYPH_SIZE = {
1663
1663
  };
1664
1664
  var TONE = {
1665
1665
  neutral: "bg-bg-secondary text-text-secondary",
1666
- brand: "bg-bg-brand-subtle text-text-brand",
1667
1666
  teal: "bg-bg-teal-subtle text-text-teal",
1668
1667
  violet: "bg-bg-violet-subtle text-text-violet",
1669
1668
  rose: "bg-bg-rose-subtle text-text-rose"
1670
1669
  };
1671
- var TINT_FAMILIES = ["brand", "teal", "violet", "rose"];
1670
+ var TINT_FAMILIES = ["teal", "violet", "rose"];
1672
1671
  function initialsOf(name) {
1673
1672
  const parts = name.trim().split(/\s+/).filter(Boolean);
1674
1673
  if (parts.length === 0) return "?";
@@ -1680,9 +1679,17 @@ function initialOf(name) {
1680
1679
  return c ? c.toUpperCase() : "?";
1681
1680
  }
1682
1681
  function tintFor(seed) {
1683
- let h = 0;
1684
- for (let i = 0; i < seed.length; i++) h = h * 31 + seed.charCodeAt(i) >>> 0;
1685
- return TINT_FAMILIES[h % TINT_FAMILIES.length];
1682
+ return TINT_FAMILIES[hashSeed(seed) % TINT_FAMILIES.length];
1683
+ }
1684
+ function hashSeed(seed) {
1685
+ let h = 2166136261;
1686
+ for (let i = 0; i < seed.length; i++) h = Math.imul(h ^ seed.charCodeAt(i), 16777619);
1687
+ h ^= h >>> 16;
1688
+ h = Math.imul(h, 2246822507);
1689
+ h ^= h >>> 13;
1690
+ h = Math.imul(h, 3266489909);
1691
+ h ^= h >>> 16;
1692
+ return h >>> 0;
1686
1693
  }
1687
1694
  function Mark({ shape, size, tone, src, label, children }) {
1688
1695
  return /* @__PURE__ */ jsxs18(
@@ -1763,7 +1770,7 @@ var Progress = React30.forwardRef(({ className, value, ...props }, ref) => /* @_
1763
1770
  children: /* @__PURE__ */ jsx37(
1764
1771
  ProgressPrimitive.Indicator,
1765
1772
  {
1766
- className: "h-full w-full flex-1 bg-text-tertiary transition-all",
1773
+ className: "h-full w-full flex-1 bg-text-tertiary transition-all duration-slide",
1767
1774
  style: { transform: `translateX(-${100 - (value || 0)}%)` }
1768
1775
  }
1769
1776
  )
@@ -1785,7 +1792,7 @@ var TabsList = React31.forwardRef(({ className, ...props }, ref) => /* @__PURE__
1785
1792
  {
1786
1793
  ref,
1787
1794
  className: cn(
1788
- "inline-flex h-10 items-center justify-center rounded-md bg-bg-secondary p-1 text-text-secondary",
1795
+ "inline-flex h-10 items-center justify-center rounded-md bg-bg-surface p-1 text-text-secondary",
1789
1796
  className
1790
1797
  ),
1791
1798
  ...props
@@ -1797,7 +1804,7 @@ var TabsTrigger = React31.forwardRef(({ className, ...props }, ref) => /* @__PUR
1797
1804
  {
1798
1805
  ref,
1799
1806
  className: cn(
1800
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all 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-elevated data-[state=active]:text-text-primary data-[state=active]:shadow-sm",
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",
1801
1808
  className
1802
1809
  ),
1803
1810
  ...props
@@ -1837,7 +1844,7 @@ var AccordionTrigger = React32.forwardRef(({ className, children, ...props }, re
1837
1844
  {
1838
1845
  ref,
1839
1846
  className: cn(
1840
- "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
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",
1841
1848
  className
1842
1849
  ),
1843
1850
  ...props,
@@ -1904,7 +1911,7 @@ var ScrollBar = React34.forwardRef(({ className, orientation = "vertical", ...pr
1904
1911
  ref,
1905
1912
  orientation,
1906
1913
  className: cn(
1907
- "flex touch-none select-none transition-colors",
1914
+ "flex touch-none select-none transition-colors duration-fast",
1908
1915
  orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
1909
1916
  orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
1910
1917
  className
@@ -2002,7 +2009,7 @@ var BreadcrumbLink = React36.forwardRef(({ asChild, className, ...props }, ref)
2002
2009
  Comp,
2003
2010
  {
2004
2011
  ref,
2005
- className: cn("transition-colors hover:text-text-primary", className),
2012
+ className: cn("transition-colors duration-fast hover:text-text-primary", className),
2006
2013
  ...props
2007
2014
  }
2008
2015
  );
@@ -2261,7 +2268,7 @@ var NavigationMenuList = React39.forwardRef(({ className, ...props }, ref) => /*
2261
2268
  NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
2262
2269
  var NavigationMenuItem = NavigationMenuPrimitive.Item;
2263
2270
  var navigationMenuTriggerStyle = cva6(
2264
- "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 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"
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"
2265
2272
  );
2266
2273
  var NavigationMenuTrigger = React39.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs25(
2267
2274
  NavigationMenuPrimitive.Trigger,
@@ -2417,7 +2424,7 @@ function ThemeToggle() {
2417
2424
  "button",
2418
2425
  {
2419
2426
  onClick: () => setTheme(next),
2420
- className: "p-2 rounded-lg text-text-secondary hover:bg-bg-secondary transition-colors",
2427
+ className: "p-2 rounded-lg text-text-secondary hover:bg-bg-secondary transition-colors duration-fast",
2421
2428
  "aria-label": label,
2422
2429
  title: label,
2423
2430
  children: /* @__PURE__ */ jsx48(Icon, { className: "w-4 h-4" })
@@ -2455,20 +2462,35 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
2455
2462
  week: "flex w-full mt-2",
2456
2463
  day: "relative p-0 text-center text-sm focus-within:relative focus-within:z-20",
2457
2464
  day_button: cn(
2458
- "inline-flex size-9 items-center justify-center rounded-md p-0 font-regular text-text-primary transition-colors",
2465
+ "inline-flex size-9 items-center justify-center rounded-md p-0 font-regular text-text-primary transition-colors duration-fast",
2459
2466
  "hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
2460
2467
  "aria-selected:opacity-100"
2461
2468
  ),
2462
- selected: "[&>button]:bg-blue-400 [&>button]:text-text-on-brand [&>button]:hover:bg-blue-350 [&>button]:hover:text-text-on-brand",
2463
- // Scope today's surface to non-selected buttons so a selected "today"
2464
- // keeps the brand fill (rdp sets aria-selected on the selected button)
2465
- // rather than colliding at equal specificity.
2466
- today: '[&>button:not([aria-selected="true"])]:bg-bg-secondary [&>button:not([aria-selected="true"])]:text-text-primary',
2469
+ // The console's selection mark, unchanged for a day: the surface step, the weight step, the
2470
+ // primary tone (Guidelines/Look/Selection weight). Hovering a chosen day holds the step —
2471
+ // `day_button`'s wash is the pointer's channel and would lighten the mark out from under it.
2472
+ selected: "[&>button]:bg-bg-sunken [&>button]:font-semibold [&>button]:text-text-primary [&>button]:hover:bg-bg-sunken",
2473
+ // Today moved off `bg-secondary` because the selection mark landed on `bg-sunken`, and in
2474
+ // dark those two measure 1.034:1 — today would have worn the chosen day's fill. A hairline
2475
+ // is the free channel: it rests at `border-default`, the kit's resting edge, where a
2476
+ // selection with no word to thicken steps to `border-strong`, so neither reads as the
2477
+ // other, and a day that is both wears the plate and the hairline at once. `border` rather
2478
+ // than a ring because the box is a fixed `size-9`, so the edge costs no layout here and
2479
+ // leaves the focus ring the one thing drawing a ring.
2480
+ today: "[&>button]:border [&>button]:border-border-default",
2467
2481
  outside: "[&>button]:text-text-tertiary [&>button]:opacity-50",
2468
2482
  disabled: "[&>button]:text-text-disabled [&>button]:opacity-50",
2469
- range_start: "[&>button]:bg-blue-400 [&>button]:text-text-on-brand rounded-l-md",
2470
- range_end: "[&>button]:bg-blue-400 [&>button]:text-text-on-brand rounded-r-md",
2471
- range_middle: "[&>button]:bg-bg-secondary [&>button]:text-text-primary [&>button]:rounded-none",
2483
+ // A range is one band, so the fill goes on the cell, which has no radius of its own to notch
2484
+ // the join with; the ends round their outer side and a one-day range rounds both. Every day
2485
+ // in a range also carries `selected`, so the band and each button's own plate are the same
2486
+ // step and meet without a seam.
2487
+ range_start: "bg-bg-sunken rounded-l-md",
2488
+ range_end: "bg-bg-sunken rounded-r-md",
2489
+ // Spanned, not chosen: the middle keeps the surface step and gives back the weight step and
2490
+ // the primary tone. `[&[data-selected]>button]` is the specificity that takes them back —
2491
+ // rdp writes `data-selected` on every cell of a range, so this beats `selected` by an
2492
+ // attribute rather than by whatever order Tailwind happens to emit two equal selectors in.
2493
+ range_middle: "bg-bg-sunken [&[data-selected]>button]:font-regular [&[data-selected]>button]:text-text-secondary",
2472
2494
  hidden: "invisible",
2473
2495
  ...classNames
2474
2496
  },
@@ -2896,7 +2918,7 @@ var DocsLink = React45.forwardRef(
2896
2918
  target: "_blank",
2897
2919
  rel: "noreferrer noopener",
2898
2920
  className: cn(
2899
- "inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-sm text-text-secondary transition-colors hover:bg-bg-secondary hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
2921
+ "inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-sm text-text-secondary transition-colors duration-fast hover:bg-bg-secondary hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
2900
2922
  className
2901
2923
  ),
2902
2924
  ...props,
@@ -3354,7 +3376,7 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
3354
3376
  "button",
3355
3377
  {
3356
3378
  type: "button",
3357
- className: "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-[5px] text-left transition-colors hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
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",
3358
3380
  children: [
3359
3381
  avatar,
3360
3382
  /* @__PURE__ */ jsxs36("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
@@ -3382,7 +3404,7 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
3382
3404
  /* @__PURE__ */ jsx61("span", { className: "block truncate text-sm font-medium text-text-primary", children: user.name }),
3383
3405
  collapsed && secondLine && /* @__PURE__ */ jsx61("span", { className: "block truncate text-xs font-regular text-text-tertiary", children: secondLine })
3384
3406
  ] }),
3385
- /* @__PURE__ */ jsx61(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
3407
+ /* @__PURE__ */ jsx61(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
3386
3408
  items.map((item, i) => {
3387
3409
  const Icon = item.icon;
3388
3410
  const content = /* @__PURE__ */ jsxs36(Fragment2, { children: [
@@ -4463,10 +4485,43 @@ var RemovableChip = React62.forwardRef(
4463
4485
  );
4464
4486
  RemovableChip.displayName = "RemovableChip";
4465
4487
 
4466
- // src/components/nav-section-label.tsx
4488
+ // src/hooks/use-fresh-highlight.ts
4467
4489
  import * as React63 from "react";
4490
+ var HOLD_MS = 3200;
4491
+ var CLEAR_MS = HOLD_MS + 900;
4492
+ 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) => {
4498
+ clearTimeout(timer.current);
4499
+ setFreshId(id);
4500
+ if (announce) setMessage(announce);
4501
+ timer.current = setTimeout(() => setFreshId(null), CLEAR_MS);
4502
+ }, []);
4503
+ const isFresh = React63.useCallback((id) => id === freshId, [freshId]);
4504
+ const freshRef = React63.useCallback((el) => {
4505
+ if (!el) return;
4506
+ const rect = el.getBoundingClientRect();
4507
+ const viewportH = window.innerHeight || document.documentElement.clientHeight;
4508
+ const offscreen = rect.top < 0 || rect.bottom > viewportH;
4509
+ if (!offscreen) return;
4510
+ const reduce = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
4511
+ el.scrollIntoView({ block: "nearest", behavior: reduce ? "auto" : "smooth" });
4512
+ }, []);
4513
+ const announcer = React63.createElement(
4514
+ "span",
4515
+ { role: "status", "aria-live": "polite", className: "sr-only" },
4516
+ message
4517
+ );
4518
+ return { isFresh, markFresh, freshRef, announcer };
4519
+ }
4520
+
4521
+ // src/components/nav-section-label.tsx
4522
+ import * as React64 from "react";
4468
4523
  import { jsx as jsx75 } from "react/jsx-runtime";
4469
- var NavSectionLabel = React63.forwardRef(
4524
+ var NavSectionLabel = React64.forwardRef(
4470
4525
  function NavSectionLabel2({ className, ...props }, ref) {
4471
4526
  return /* @__PURE__ */ jsx75(
4472
4527
  "div",
@@ -4481,7 +4536,7 @@ var NavSectionLabel = React63.forwardRef(
4481
4536
  NavSectionLabel.displayName = "NavSectionLabel";
4482
4537
 
4483
4538
  // src/components/menu-popup.tsx
4484
- import * as React64 from "react";
4539
+ import * as React65 from "react";
4485
4540
  import { jsx as jsx76, jsxs as jsxs49 } from "react/jsx-runtime";
4486
4541
  function MenuPopup({
4487
4542
  trigger,
@@ -4511,7 +4566,7 @@ function MenuPopup({
4511
4566
  )
4512
4567
  ] });
4513
4568
  }
4514
- var MenuDivider = React64.forwardRef(
4569
+ var MenuDivider = React65.forwardRef(
4515
4570
  function MenuDivider2({ className, ...props }, ref) {
4516
4571
  return /* @__PURE__ */ jsx76(
4517
4572
  "div",
@@ -4527,11 +4582,11 @@ var MenuDivider = React64.forwardRef(
4527
4582
  MenuDivider.displayName = "MenuDivider";
4528
4583
 
4529
4584
  // src/components/sidebar-product-header.tsx
4530
- import * as React65 from "react";
4585
+ import * as React66 from "react";
4531
4586
  import { Slot as Slot4 } from "@radix-ui/react-slot";
4532
4587
  import { ChevronsUpDown as ChevronsUpDown2 } from "lucide-react";
4533
4588
  import { Fragment as Fragment7, jsx as jsx77, jsxs as jsxs50 } from "react/jsx-runtime";
4534
- var SidebarProductHeader = React65.forwardRef(
4589
+ var SidebarProductHeader = React66.forwardRef(
4535
4590
  function SidebarProductHeader2({ name, icon, trailing, asChild = false, className, children, ...props }, ref) {
4536
4591
  const adornment = trailing === void 0 ? /* @__PURE__ */ jsx77(ChevronsUpDown2, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }) : trailing;
4537
4592
  const content = /* @__PURE__ */ jsxs50(Fragment7, { children: [
@@ -4541,8 +4596,8 @@ var SidebarProductHeader = React65.forwardRef(
4541
4596
  ] });
4542
4597
  const classes = cn("flex w-full items-center gap-2.5 rounded-xl px-1.5 py-0 text-left", className);
4543
4598
  if (asChild) {
4544
- const child = React65.Children.only(children);
4545
- return /* @__PURE__ */ jsx77(Slot4, { ref, className: classes, ...props, children: React65.cloneElement(child, void 0, content) });
4599
+ const child = React66.Children.only(children);
4600
+ return /* @__PURE__ */ jsx77(Slot4, { ref, className: classes, ...props, children: React66.cloneElement(child, void 0, content) });
4546
4601
  }
4547
4602
  return /* @__PURE__ */ jsx77("button", { ref, type: "button", className: classes, ...props, children: content });
4548
4603
  }
@@ -4552,7 +4607,7 @@ SidebarProductHeader.displayName = "SidebarProductHeader";
4552
4607
  // src/components/org-product-switcher.tsx
4553
4608
  import { ChevronsUpDown as ChevronsUpDown3, Check as Check9 } from "lucide-react";
4554
4609
  import { Fragment as Fragment8, jsx as jsx78, jsxs as jsxs51 } from "react/jsx-runtime";
4555
- var triggerBox = "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-1 text-left transition-colors hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
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";
4556
4611
  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";
4557
4612
  var sectionLabel = "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary";
4558
4613
  var NO_ORG_LABEL = "Select an organization\u2026";
@@ -4643,7 +4698,7 @@ function OrgProductSwitcher({
4643
4698
  o.id === activeOrgId && /* @__PURE__ */ jsx78(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
4644
4699
  ] }, o.id)),
4645
4700
  products.length > 0 && /* @__PURE__ */ jsxs51(Fragment8, { children: [
4646
- /* @__PURE__ */ jsx78(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
4701
+ /* @__PURE__ */ jsx78(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
4647
4702
  /* @__PURE__ */ jsx78(DropdownMenuLabel, { className: sectionLabel, children: orgName ? `${orgName} \xB7 Products` : "Products" }),
4648
4703
  products.map((p) => /* @__PURE__ */ jsxs51(DropdownMenuItem, { className: menuItem, onSelect: () => onProductSelect?.(p.id), children: [
4649
4704
  /* @__PURE__ */ jsx78(Mark2, { item: p, size: "sm", reserve: true }),
@@ -4652,7 +4707,7 @@ function OrgProductSwitcher({
4652
4707
  ] }, p.id))
4653
4708
  ] }),
4654
4709
  actions && actions.length > 0 && /* @__PURE__ */ jsxs51(Fragment8, { children: [
4655
- /* @__PURE__ */ jsx78(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
4710
+ /* @__PURE__ */ jsx78(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
4656
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: [
4657
4712
  a.icon,
4658
4713
  a.label
@@ -4672,7 +4727,7 @@ OrgProductSwitcher.displayName = "OrgProductSwitcher";
4672
4727
  import { ArrowLeft as ArrowLeft3 } from "lucide-react";
4673
4728
  import { jsx as jsx79, jsxs as jsxs52 } from "react/jsx-runtime";
4674
4729
  var focusRing = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
4675
- var arrowPlate = "flex size-5 items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--text-primary)_12%,transparent)] hover:text-text-primary";
4730
+ 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";
4676
4731
  var arrowBox = "flex shrink-0 cursor-pointer items-center rounded-xl py-2 pr-0 pl-2.5 text-text-secondary";
4677
4732
  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";
4678
4733
  var Arrow = () => /* @__PURE__ */ jsx79(ArrowLeft3, { size: 16, "aria-hidden": "true" });
@@ -4730,9 +4785,9 @@ function SidebarBackHeader({
4730
4785
  SidebarBackHeader.displayName = "SidebarBackHeader";
4731
4786
 
4732
4787
  // src/components/top-bar.tsx
4733
- import * as React66 from "react";
4788
+ import * as React67 from "react";
4734
4789
  import { jsx as jsx80, jsxs as jsxs53 } from "react/jsx-runtime";
4735
- var TopBar = React66.forwardRef(
4790
+ var TopBar = React67.forwardRef(
4736
4791
  ({ left, right, className, ...props }, ref) => /* @__PURE__ */ jsxs53("div", { ref, className: cn("flex w-full items-center gap-1", className), ...props, children: [
4737
4792
  left,
4738
4793
  right && /* @__PURE__ */ jsx80("div", { className: "ml-auto flex items-center gap-2", children: right })
@@ -4741,9 +4796,9 @@ var TopBar = React66.forwardRef(
4741
4796
  TopBar.displayName = "TopBar";
4742
4797
 
4743
4798
  // src/components/top-bar-utilities.tsx
4744
- import * as React67 from "react";
4799
+ import * as React68 from "react";
4745
4800
  import { jsx as jsx81, jsxs as jsxs54 } from "react/jsx-runtime";
4746
- var TopBarUtilities = React67.forwardRef(
4801
+ var TopBarUtilities = React68.forwardRef(
4747
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: [
4748
4803
  /* @__PURE__ */ jsx81(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx81(Button, { variant: "ghost", size: "sm", icon, "aria-label": name, onClick }) }),
4749
4804
  /* @__PURE__ */ jsx81(TooltipContent, { children: name })
@@ -4752,10 +4807,10 @@ var TopBarUtilities = React67.forwardRef(
4752
4807
  TopBarUtilities.displayName = "TopBarUtilities";
4753
4808
 
4754
4809
  // src/components/grid.tsx
4755
- import * as React68 from "react";
4810
+ import * as React69 from "react";
4756
4811
  import { Slot as Slot5 } from "@radix-ui/react-slot";
4757
4812
  import { jsx as jsx82 } from "react/jsx-runtime";
4758
- var Grid = React68.forwardRef(
4813
+ var Grid = React69.forwardRef(
4759
4814
  ({ fluid = false, asChild = false, className, ...props }, ref) => {
4760
4815
  const Comp = asChild ? Slot5 : "div";
4761
4816
  return /* @__PURE__ */ jsx82(
@@ -4776,7 +4831,7 @@ var Grid = React68.forwardRef(
4776
4831
  Grid.displayName = "Grid";
4777
4832
 
4778
4833
  // src/components/col.tsx
4779
- import * as React69 from "react";
4834
+ import * as React70 from "react";
4780
4835
  import { Slot as Slot6 } from "@radix-ui/react-slot";
4781
4836
  import { jsx as jsx83 } from "react/jsx-runtime";
4782
4837
  var TIER_MAX = { base: 4, md: 8, xl: 12 };
@@ -4898,7 +4953,7 @@ function responsiveClasses(span, offset) {
4898
4953
  }
4899
4954
  return cn(...spanClasses, ...startClasses);
4900
4955
  }
4901
- var Col = React69.forwardRef(
4956
+ var Col = React70.forwardRef(
4902
4957
  ({ span, offset, asChild = false, className, ...props }, ref) => {
4903
4958
  const Comp = asChild ? Slot6 : "div";
4904
4959
  return /* @__PURE__ */ jsx83(Comp, { ref, className: cn(responsiveClasses(span, offset), className), ...props });
@@ -4917,7 +4972,7 @@ function PageColumn({ className, width = "reading", ...props }) {
4917
4972
  }
4918
4973
 
4919
4974
  // src/components/code-block.tsx
4920
- import * as React70 from "react";
4975
+ import * as React71 from "react";
4921
4976
  import { jsx as jsx85, jsxs as jsxs55 } from "react/jsx-runtime";
4922
4977
  var TOKEN_CLASS = {
4923
4978
  comment: "text-text-tertiary italic",
@@ -5089,11 +5144,11 @@ function dropLeading(tokens, count) {
5089
5144
  }
5090
5145
  return out;
5091
5146
  }
5092
- var CodeBlock = React70.forwardRef(
5147
+ var CodeBlock = React71.forwardRef(
5093
5148
  ({ code, lang = "tsx", variant = "default", copy = false, filename, scroll = false, highlightLines, showLineNumbers = false, className, ...props }, ref) => {
5094
- const lines = React70.useMemo(() => tokenizeLines(code, lang), [code, lang]);
5095
- const rawLines = React70.useMemo(() => code.split("\n"), [code]);
5096
- const highlighted = React70.useMemo(() => parseHighlightLines(highlightLines), [highlightLines]);
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]);
5097
5152
  const isDiff = variant === "diff";
5098
5153
  const isTerminal = variant === "terminal";
5099
5154
  const showCopy = copy && !isTerminal;
@@ -5168,7 +5223,7 @@ var CodeBlock = React70.forwardRef(
5168
5223
  }
5169
5224
  );
5170
5225
  CodeBlock.displayName = "CodeBlock";
5171
- var Code = React70.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx85(
5226
+ var Code = React71.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx85(
5172
5227
  "code",
5173
5228
  {
5174
5229
  ref,
@@ -5182,10 +5237,10 @@ var Code = React70.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
5182
5237
  Code.displayName = "Code";
5183
5238
 
5184
5239
  // src/components/grid-overlay.tsx
5185
- import * as React71 from "react";
5240
+ import * as React72 from "react";
5186
5241
  import { jsx as jsx86 } from "react/jsx-runtime";
5187
5242
  var BASELINE = "var(--grid-gutter) / 2";
5188
- var GridOverlay = React71.forwardRef(
5243
+ var GridOverlay = React72.forwardRef(
5189
5244
  ({ columns, baseline = false, className, style, ...props }, ref) => {
5190
5245
  const count = Number.isFinite(columns) ? Math.max(1, Math.floor(columns)) : 1;
5191
5246
  return /* @__PURE__ */ jsx86(
@@ -5213,7 +5268,7 @@ var GridOverlay = React71.forwardRef(
5213
5268
  GridOverlay.displayName = "GridOverlay";
5214
5269
 
5215
5270
  // src/components/attachment-chip.tsx
5216
- import * as React72 from "react";
5271
+ import * as React73 from "react";
5217
5272
  import { cva as cva8 } from "class-variance-authority";
5218
5273
  import { Link2, Clock, Plus as Plus2 } from "lucide-react";
5219
5274
  import { jsx as jsx87, jsxs as jsxs56 } from "react/jsx-runtime";
@@ -5235,7 +5290,7 @@ var stateIcons = {
5235
5290
  requested: Clock,
5236
5291
  available: Plus2
5237
5292
  };
5238
- var AttachmentChip = React72.forwardRef(
5293
+ var AttachmentChip = React73.forwardRef(
5239
5294
  ({ state, account, icon, hideIcon = false, className, ...props }, ref) => {
5240
5295
  const Icon = icon ?? stateIcons[state ?? "attached"];
5241
5296
  return /* @__PURE__ */ jsxs56("span", { ref, className: cn(attachmentChipVariants({ state }), className), ...props, children: [
@@ -5247,7 +5302,7 @@ var AttachmentChip = React72.forwardRef(
5247
5302
  AttachmentChip.displayName = "AttachmentChip";
5248
5303
 
5249
5304
  // src/components/connector-card.tsx
5250
- import * as React73 from "react";
5305
+ import * as React74 from "react";
5251
5306
  import { AlertTriangle, ChevronDown as ChevronDown6 } from "lucide-react";
5252
5307
  import { Fragment as Fragment9, jsx as jsx88, jsxs as jsxs57 } from "react/jsx-runtime";
5253
5308
  var originLabels = {
@@ -5262,7 +5317,7 @@ var statusLabels = {
5262
5317
  function monogram(name) {
5263
5318
  return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
5264
5319
  }
5265
- var ConnectorCard = React73.forwardRef(
5320
+ var ConnectorCard = React74.forwardRef(
5266
5321
  ({
5267
5322
  name,
5268
5323
  kind,
@@ -5366,7 +5421,7 @@ var ConnectorCard = React73.forwardRef(
5366
5421
  ChevronDown6,
5367
5422
  {
5368
5423
  "aria-hidden": "true",
5369
- className: "size-4 shrink-0 text-text-tertiary transition-transform group-data-[state=open]:rotate-180"
5424
+ className: "size-4 shrink-0 text-text-tertiary transition-transform duration-fast group-data-[state=open]:rotate-180"
5370
5425
  }
5371
5426
  )
5372
5427
  ] })
@@ -5386,12 +5441,12 @@ var ConnectorCard = React73.forwardRef(
5386
5441
  ConnectorCard.displayName = "ConnectorCard";
5387
5442
 
5388
5443
  // src/components/request-row.tsx
5389
- import * as React74 from "react";
5444
+ import * as React75 from "react";
5390
5445
  import { Fragment as Fragment10, jsx as jsx89, jsxs as jsxs58 } from "react/jsx-runtime";
5391
5446
  function monogram2(name) {
5392
5447
  return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
5393
5448
  }
5394
- var RequestRow = React74.forwardRef(
5449
+ var RequestRow = React75.forwardRef(
5395
5450
  ({ surface, name, state, glyph, subtitle, account, onApprove, onDeny, onRequest, onRevoke, action, className, ...props }, ref) => {
5396
5451
  let controls = action;
5397
5452
  if (controls === void 0) {
@@ -5443,7 +5498,7 @@ var RequestRow = React74.forwardRef(
5443
5498
  RequestRow.displayName = "RequestRow";
5444
5499
 
5445
5500
  // src/components/feedback-button.tsx
5446
- import * as React75 from "react";
5501
+ import * as React76 from "react";
5447
5502
  import { MessageSquare, Loader2 as Loader23, CheckCircle2 } from "lucide-react";
5448
5503
  import { jsx as jsx90, jsxs as jsxs59 } from "react/jsx-runtime";
5449
5504
  var TITLE_MAX = 256;
@@ -5459,15 +5514,15 @@ var DEFAULT_LABELS = {
5459
5514
  };
5460
5515
  function FeedbackButton({ onSubmit, labels, className }) {
5461
5516
  const l = { ...DEFAULT_LABELS, ...labels };
5462
- const uid = React75.useId();
5517
+ const uid = React76.useId();
5463
5518
  const titleId = `${uid}-title`;
5464
5519
  const detailsId = `${uid}-details`;
5465
5520
  const titleErrId = `${uid}-title-error`;
5466
5521
  const detailsErrId = `${uid}-details-error`;
5467
- const [open, setOpen] = React75.useState(false);
5468
- const [status, setStatus] = React75.useState("idle");
5469
- const [title, setTitle] = React75.useState("");
5470
- const [details, setDetails] = React75.useState("");
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("");
5471
5526
  const titleTooLong = title.length > TITLE_MAX;
5472
5527
  const detailsTooLong = details.length > DETAILS_MAX;
5473
5528
  const titleEmpty = title.trim().length === 0;
@@ -5601,11 +5656,11 @@ function isNotificationSettled(item) {
5601
5656
  }
5602
5657
 
5603
5658
  // src/components/notification-bell.tsx
5604
- import * as React77 from "react";
5659
+ import * as React78 from "react";
5605
5660
  import { BellRing, Settings } from "lucide-react";
5606
5661
 
5607
5662
  // src/components/notification-row.tsx
5608
- import * as React76 from "react";
5663
+ import * as React77 from "react";
5609
5664
 
5610
5665
  // src/components/notification-parts.tsx
5611
5666
  import { Check as Check10 } from "lucide-react";
@@ -5640,7 +5695,7 @@ function DeepLinkControl({
5640
5695
 
5641
5696
  // src/components/notification-row.tsx
5642
5697
  import { jsx as jsx92, jsxs as jsxs60 } from "react/jsx-runtime";
5643
- var NotificationRow = React76.forwardRef(
5698
+ var NotificationRow = React77.forwardRef(
5644
5699
  ({ item, onItemClick, onActionClick, onMarkRead, formatAge, className, ...props }, ref) => {
5645
5700
  const settled = isNotificationSettled(item);
5646
5701
  const unread = !settled && !item.read;
@@ -5704,7 +5759,7 @@ var NotificationRow = React76.forwardRef(
5704
5759
  onClick: () => onActionClick?.(item, action),
5705
5760
  className: cn(
5706
5761
  rowControlHitArea,
5707
- chip ? "rounded-md px-2.5 py-1 text-xs font-medium transition-colors" : "text-xs font-semibold text-text-secondary transition-opacity hover:opacity-80",
5762
+ 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",
5708
5763
  action.variant === "primary" && "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover",
5709
5764
  action.variant === "destructive" && "bg-bg-elevated text-text-danger hover:bg-bg-sunken"
5710
5765
  ),
@@ -5721,7 +5776,7 @@ var NotificationRow = React76.forwardRef(
5721
5776
  onClick: () => onItemClick?.(item),
5722
5777
  className: cn(
5723
5778
  rowControlHitArea,
5724
- "text-xs font-semibold text-text-brand transition-opacity hover:opacity-80"
5779
+ "text-xs font-semibold text-text-brand transition-opacity duration-fast hover:opacity-80"
5725
5780
  )
5726
5781
  }
5727
5782
  )
@@ -5736,7 +5791,7 @@ NotificationRow.displayName = "NotificationRow";
5736
5791
 
5737
5792
  // src/components/notification-bell.tsx
5738
5793
  import { jsx as jsx93, jsxs as jsxs61 } from "react/jsx-runtime";
5739
- var NotificationBell = React77.forwardRef(
5794
+ var NotificationBell = React78.forwardRef(
5740
5795
  ({
5741
5796
  items,
5742
5797
  unreadCount,
@@ -5764,7 +5819,7 @@ var NotificationBell = React77.forwardRef(
5764
5819
  type: "button",
5765
5820
  "aria-label": "Notifications",
5766
5821
  className: cn(
5767
- "relative flex size-8 items-center justify-center rounded-lg text-text-secondary transition-colors hover:bg-bg-elevated hover:text-text-primary data-[state=open]:bg-bg-brand-subtle data-[state=open]:text-text-brand",
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",
5768
5823
  className
5769
5824
  ),
5770
5825
  children: [
@@ -5789,7 +5844,7 @@ var NotificationBell = React77.forwardRef(
5789
5844
  {
5790
5845
  type: "button",
5791
5846
  onClick: () => onMarkAllRead?.(),
5792
- className: "text-sm font-medium text-text-tertiary transition-colors hover:text-text-primary",
5847
+ className: "text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
5793
5848
  children: "Mark all read"
5794
5849
  }
5795
5850
  ),
@@ -5799,7 +5854,7 @@ var NotificationBell = React77.forwardRef(
5799
5854
  type: "button",
5800
5855
  "aria-label": "Notification settings",
5801
5856
  onClick: () => onOpenSettings(),
5802
- className: "flex size-6 items-center justify-center rounded-md text-text-tertiary transition-colors hover:bg-bg-surface hover:text-text-primary",
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",
5803
5858
  children: /* @__PURE__ */ jsx93(Settings, { className: "size-[15px]", "aria-hidden": "true" })
5804
5859
  }
5805
5860
  )
@@ -5822,7 +5877,7 @@ var NotificationBell = React77.forwardRef(
5822
5877
  {
5823
5878
  type: "button",
5824
5879
  onClick: () => onOpenArchive(),
5825
- className: "flex w-full shrink-0 items-center justify-center px-5 py-2.5 text-sm font-medium text-text-brand transition-colors hover:bg-bg-surface",
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",
5826
5881
  children: hidden > 0 ? `Open notifications archive, ${hidden} more` : "Open notifications archive"
5827
5882
  }
5828
5883
  )
@@ -5835,11 +5890,11 @@ var NotificationBell = React77.forwardRef(
5835
5890
  NotificationBell.displayName = "NotificationBell";
5836
5891
 
5837
5892
  // src/components/notification-center.tsx
5838
- import * as React78 from "react";
5893
+ import * as React79 from "react";
5839
5894
  import { Check as Check11, Search as Search2 } from "lucide-react";
5840
5895
  import { jsx as jsx94, jsxs as jsxs62 } from "react/jsx-runtime";
5841
- var chipBase = "rounded-lg px-3 py-1.5 text-sm font-medium transition-colors";
5842
- var chipOn = "bg-bg-brand-subtle text-text-brand";
5896
+ var chipBase = "rounded-md px-3 py-1.5 text-sm font-medium transition-colors duration-fast";
5897
+ var chipOn = "bg-bg-sunken font-semibold text-text-primary";
5843
5898
  var chipOff = "bg-bg-elevated text-text-secondary hover:text-text-primary";
5844
5899
  function CenterRow({
5845
5900
  item,
@@ -5894,14 +5949,14 @@ function CenterRow({
5894
5949
  onClick: () => onDeepLinkClick?.(item),
5895
5950
  className: cn(
5896
5951
  rowControlHitArea,
5897
- "inline-flex items-center gap-1 text-sm font-medium text-text-brand transition-colors hover:text-text-primary"
5952
+ "inline-flex items-center gap-1 text-sm font-medium text-text-brand transition-colors duration-fast hover:text-text-primary"
5898
5953
  )
5899
5954
  }
5900
5955
  )
5901
5956
  ] })
5902
5957
  ] });
5903
5958
  }
5904
- var NotificationCenter = React78.forwardRef(
5959
+ var NotificationCenter = React79.forwardRef(
5905
5960
  ({
5906
5961
  items,
5907
5962
  header = true,
@@ -5918,16 +5973,16 @@ var NotificationCenter = React78.forwardRef(
5918
5973
  formatAge,
5919
5974
  className
5920
5975
  }, ref) => {
5921
- const [status, setStatus] = React78.useState("all");
5922
- const [source, setSource] = React78.useState("all");
5923
- const [product, setProduct] = React78.useState("all");
5924
- const [query, setQuery] = React78.useState("");
5925
- const [limit, setLimit] = React78.useState(pageSize);
5926
- const age = React78.useCallback(
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(
5927
5982
  (createdAt) => formatAge ? formatAge(createdAt) : formatRelativeAge(createdAt),
5928
5983
  [formatAge]
5929
5984
  );
5930
- const sourceChips = React78.useMemo(
5985
+ const sourceChips = React79.useMemo(
5931
5986
  () => sources ?? Array.from(new Set(items.map((n) => n.source))),
5932
5987
  [sources, items]
5933
5988
  );
@@ -5949,7 +6004,7 @@ var NotificationCenter = React78.forwardRef(
5949
6004
  {
5950
6005
  type: "button",
5951
6006
  onClick: () => onMarkAllRead(),
5952
- className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors hover:text-text-primary",
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",
5953
6008
  children: "Read all"
5954
6009
  }
5955
6010
  )
@@ -6046,7 +6101,7 @@ var NotificationCenter = React78.forwardRef(
6046
6101
  {
6047
6102
  type: "button",
6048
6103
  onClick: () => setLimit((l) => l + pageSize),
6049
- className: "mt-1 rounded-lg bg-bg-elevated px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors hover:bg-bg-surface hover:text-text-primary",
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",
6050
6105
  children: [
6051
6106
  "Load ",
6052
6107
  remaining,
@@ -6061,7 +6116,7 @@ var NotificationCenter = React78.forwardRef(
6061
6116
  NotificationCenter.displayName = "NotificationCenter";
6062
6117
 
6063
6118
  // src/components/notification-settings.tsx
6064
- import * as React79 from "react";
6119
+ import * as React80 from "react";
6065
6120
  import { Moon as Moon2, Plus as Plus3, Volume2 } from "lucide-react";
6066
6121
  import { Fragment as Fragment11, jsx as jsx95, jsxs as jsxs63 } from "react/jsx-runtime";
6067
6122
  var THRESHOLDS = [
@@ -6088,7 +6143,7 @@ function ThresholdControl({
6088
6143
  }
6089
6144
  );
6090
6145
  }
6091
- var NotificationSettings = React79.forwardRef(
6146
+ var NotificationSettings = React80.forwardRef(
6092
6147
  ({
6093
6148
  subscriptions,
6094
6149
  value,
@@ -6101,7 +6156,7 @@ var NotificationSettings = React79.forwardRef(
6101
6156
  pushSlot,
6102
6157
  className
6103
6158
  }, ref) => {
6104
- const [tab, setTab] = React79.useState(DEFAULT_KEY);
6159
+ const [tab, setTab] = React80.useState(DEFAULT_KEY);
6105
6160
  const isDefault = tab === DEFAULT_KEY;
6106
6161
  const defaults = value[DEFAULT_KEY] ?? { thresholds: {} };
6107
6162
  const customized = !isDefault && Object.prototype.hasOwnProperty.call(value, tab);
@@ -6183,7 +6238,7 @@ var NotificationSettings = React79.forwardRef(
6183
6238
  {
6184
6239
  type: "button",
6185
6240
  onClick: () => onUnmute?.(m.source),
6186
- className: "rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors hover:bg-bg-surface",
6241
+ className: "rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
6187
6242
  children: "Unmute"
6188
6243
  }
6189
6244
  )
@@ -6217,7 +6272,7 @@ var NotificationSettings = React79.forwardRef(
6217
6272
  {
6218
6273
  type: "button",
6219
6274
  onClick: customize,
6220
- className: "mt-5 inline-flex items-center gap-1.5 rounded-lg bg-bg-brand px-3.5 py-2 text-sm font-semibold text-text-on-brand transition-colors hover:bg-bg-brand-hover",
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",
6221
6276
  children: [
6222
6277
  /* @__PURE__ */ jsx95(Plus3, { className: "size-4", "aria-hidden": "true" }),
6223
6278
  " Customize for ",
@@ -6239,7 +6294,7 @@ var NotificationSettings = React79.forwardRef(
6239
6294
  {
6240
6295
  type: "button",
6241
6296
  onClick: resetToDefault,
6242
- className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors hover:text-text-danger",
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",
6243
6298
  children: "Reset to Default"
6244
6299
  }
6245
6300
  )
@@ -6252,14 +6307,14 @@ var NotificationSettings = React79.forwardRef(
6252
6307
  NotificationSettings.displayName = "NotificationSettings";
6253
6308
 
6254
6309
  // src/components/notification-toast.tsx
6255
- import * as React80 from "react";
6310
+ import * as React81 from "react";
6256
6311
  import { X as X4 } from "lucide-react";
6257
6312
  import { jsx as jsx96, jsxs as jsxs64 } from "react/jsx-runtime";
6258
- var chipBase2 = "rounded-lg px-2.5 py-1 text-sm font-medium transition-colors";
6313
+ var chipBase2 = "rounded-lg px-2.5 py-1 text-sm font-medium transition-colors duration-fast";
6259
6314
  var chipPrimary = "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover";
6260
6315
  var chipDestructive = "bg-bg-elevated text-text-danger hover:bg-bg-surface";
6261
- var linkAction = "text-sm font-semibold text-text-brand transition-colors hover:text-text-primary";
6262
- var NotificationToast = React80.forwardRef(
6316
+ var linkAction = "text-sm font-semibold text-text-brand transition-colors duration-fast hover:text-text-primary";
6317
+ var NotificationToast = React81.forwardRef(
6263
6318
  ({
6264
6319
  item,
6265
6320
  showSource = true,
@@ -6276,7 +6331,7 @@ var NotificationToast = React80.forwardRef(
6276
6331
  const actions = item.actions ?? [];
6277
6332
  const percent = progress === void 0 || !Number.isFinite(progress) ? void 0 : Math.min(100, Math.max(0, progress));
6278
6333
  const progressLine = progressLabel === void 0 && percent !== void 0 ? `live, ${Math.round(percent)}%` : progressLabel;
6279
- const barId = React80.useId();
6334
+ const barId = React81.useId();
6280
6335
  const hasProgressLine = progressLine !== null && progressLine !== void 0;
6281
6336
  return /* @__PURE__ */ jsxs64(
6282
6337
  "div",
@@ -6300,7 +6355,7 @@ var NotificationToast = React80.forwardRef(
6300
6355
  type: "button",
6301
6356
  "aria-label": dismissLabel,
6302
6357
  onClick: () => onDismiss(item),
6303
- className: "flex size-5 shrink-0 items-center justify-center rounded-md text-text-tertiary transition-colors hover:bg-bg-surface hover:text-text-primary",
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",
6304
6359
  children: /* @__PURE__ */ jsx96(X4, { className: "size-3.5", "aria-hidden": "true" })
6305
6360
  }
6306
6361
  )
@@ -6354,7 +6409,7 @@ var NotificationToast = React80.forwardRef(
6354
6409
  NotificationToast.displayName = "NotificationToast";
6355
6410
 
6356
6411
  // src/components/notification-toaster.tsx
6357
- import * as React81 from "react";
6412
+ import * as React82 from "react";
6358
6413
  import { jsx as jsx97 } from "react/jsx-runtime";
6359
6414
  var positions = {
6360
6415
  "bottom-right": "bottom-6 right-6 flex-col",
@@ -6362,7 +6417,7 @@ var positions = {
6362
6417
  "top-right": "top-6 right-6 flex-col-reverse",
6363
6418
  "top-left": "top-6 left-6 flex-col-reverse"
6364
6419
  };
6365
- var NotificationToaster = React81.forwardRef(
6420
+ var NotificationToaster = React82.forwardRef(
6366
6421
  ({
6367
6422
  items,
6368
6423
  dwell,
@@ -6379,15 +6434,15 @@ var NotificationToaster = React81.forwardRef(
6379
6434
  className
6380
6435
  }, ref) => {
6381
6436
  const shown = items.slice(0, max);
6382
- const [paused, setPaused] = React81.useState(false);
6383
- const onDismissRef = React81.useRef(onDismiss);
6437
+ const [paused, setPaused] = React82.useState(false);
6438
+ const onDismissRef = React82.useRef(onDismiss);
6384
6439
  onDismissRef.current = onDismiss;
6385
6440
  const fyiDwell = dwell?.fyi;
6386
6441
  const importantDwell = dwell?.important;
6387
6442
  const criticalDwell = dwell?.critical;
6388
- const remaining = React81.useRef(/* @__PURE__ */ new Map());
6443
+ const remaining = React82.useRef(/* @__PURE__ */ new Map());
6389
6444
  const liveIds = shown.map((item) => `${item.id}:${item.severity}`).join(" ");
6390
- React81.useEffect(() => {
6445
+ React82.useEffect(() => {
6391
6446
  const owedById = remaining.current;
6392
6447
  const dwellSeconds = {
6393
6448
  fyi: fyiDwell ?? TOAST_DWELL.fyi,
@@ -6715,11 +6770,11 @@ var COUNTRY_OPTIONS = [
6715
6770
  ];
6716
6771
 
6717
6772
  // src/components/organization-onboarding-form.tsx
6718
- import * as React82 from "react";
6773
+ import * as React83 from "react";
6719
6774
 
6720
6775
  // src/lib/auth-surface.ts
6721
- 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 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]";
6722
- var AUTH_QUIET_BUTTON = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-border-default bg-transparent px-[14px] text-[14.5px] font-medium tracking-[-0.005em] text-text-secondary transition-colors hover:bg-bg-secondary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand";
6776
+ 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]";
6777
+ var AUTH_QUIET_BUTTON = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-border-default bg-transparent px-[14px] text-[14.5px] font-medium tracking-[-0.005em] text-text-secondary transition-colors duration-fast hover:bg-bg-secondary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand";
6723
6778
  var AUTH_BUTTON_SHADOW = "var(--auth-btn-shadow)";
6724
6779
 
6725
6780
  // src/components/organization-onboarding-form.tsx
@@ -6758,22 +6813,22 @@ function OrganizationOnboardingForm({
6758
6813
  onCancel,
6759
6814
  className
6760
6815
  }) {
6761
- const [name, setName] = React82.useState(defaultValues?.name ?? "");
6762
- const [legalName, setLegalName] = React82.useState(defaultValues?.legal_name ?? "");
6763
- const [ownerName, setOwnerName] = React82.useState(defaultValues?.owner_name ?? "");
6764
- const [countryOfIncorporation, setCountryOfIncorporation] = React82.useState(
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(
6765
6820
  defaultValues?.country_of_incorporation ?? ""
6766
6821
  );
6767
- const [residencyCountry, setResidencyCountry] = React82.useState(
6822
+ const [residencyCountry, setResidencyCountry] = React83.useState(
6768
6823
  defaultValues?.residency_country ?? ""
6769
6824
  );
6770
- const [owners, setOwners] = React82.useState(
6825
+ const [owners, setOwners] = React83.useState(
6771
6826
  () => initialRows(defaultValues?.beneficial_owners)
6772
6827
  );
6773
- const [ownershipConfirmed, setOwnershipConfirmed] = React82.useState(false);
6774
- const [confirmationAttempted, setConfirmationAttempted] = React82.useState(false);
6775
- const nextKeyRef = React82.useRef(owners.length);
6776
- const submittingRef = React82.useRef(false);
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);
6777
6832
  const trimmed = name.trim();
6778
6833
  const filledOwners = owners.filter((row) => !isRowBlank(row));
6779
6834
  const ownerShares = filledOwners.map((row) => parseShare(row.share));
@@ -6827,7 +6882,7 @@ function OrganizationOnboardingForm({
6827
6882
  ...needsOwnershipConfirmation ? { ownership_confirmed: ownershipConfirmed } : {}
6828
6883
  });
6829
6884
  };
6830
- React82.useEffect(() => {
6885
+ React83.useEffect(() => {
6831
6886
  submittingRef.current = false;
6832
6887
  }, [
6833
6888
  name,
@@ -7053,7 +7108,7 @@ function OrganizationOnboardingForm({
7053
7108
  }
7054
7109
 
7055
7110
  // src/components/list-columns.tsx
7056
- import * as React83 from "react";
7111
+ import * as React84 from "react";
7057
7112
  import { jsx as jsx99, jsxs as jsxs66 } from "react/jsx-runtime";
7058
7113
  var CELL_WIDTH = { 20: "w-20", 24: "w-24", 28: "w-28", 32: "w-32" };
7059
7114
  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";
@@ -7072,7 +7127,7 @@ function warnDuplicateKeys(columns, where) {
7072
7127
  seen.add(c.key);
7073
7128
  }
7074
7129
  }
7075
- var ListHeader = React83.forwardRef(function ListHeader2({ lead, columns, mark = true, trailing = true, className, ...props }, ref) {
7130
+ var ListHeader = React84.forwardRef(function ListHeader2({ lead, columns, mark = true, trailing = true, className, ...props }, ref) {
7076
7131
  warnDuplicateKeys(columns, "ListHeader");
7077
7132
  return /* @__PURE__ */ jsxs66("div", { ref, className: cn(headerClass, className), ...props, children: [
7078
7133
  mark && /* @__PURE__ */ jsx99("span", { className: "size-8 shrink-0", "aria-hidden": true }),
@@ -7086,7 +7141,7 @@ function cellValue(values, column) {
7086
7141
  const value = values[column.key];
7087
7142
  return value === void 0 || value === null || value === "" ? column.fallback : value;
7088
7143
  }
7089
- var ListCells = React83.forwardRef(function ListCells2({ columns, values, className, ...props }, ref) {
7144
+ var ListCells = React84.forwardRef(function ListCells2({ columns, values, className, ...props }, ref) {
7090
7145
  warnDuplicateKeys(columns, "ListCells");
7091
7146
  return /* @__PURE__ */ jsx99("span", { ref, className: cn(cellsClass, className), ...props, children: columns.map((c) => /* @__PURE__ */ jsx99(
7092
7147
  "span",
@@ -7101,7 +7156,7 @@ ListHeader.displayName = "ListHeader";
7101
7156
  ListCells.displayName = "ListCells";
7102
7157
 
7103
7158
  // src/components/theme-picker.tsx
7104
- import * as React84 from "react";
7159
+ import * as React85 from "react";
7105
7160
  import { Check as Check12, Monitor } from "lucide-react";
7106
7161
  import { jsx as jsx100, jsxs as jsxs67 } from "react/jsx-runtime";
7107
7162
  var THEME_SWATCHES = {
@@ -7150,11 +7205,11 @@ function Panels({ palette }) {
7150
7205
  )
7151
7206
  ] });
7152
7207
  }
7153
- var autoPlateClass = "flex h-full items-center justify-center bg-bg-secondary";
7208
+ var autoPlateClass = "flex h-full items-center justify-center bg-bg-surface";
7154
7209
  var previewClass = "block h-28 overflow-hidden rounded-lg border border-border-default";
7155
- var cardClass = "grid gap-2 rounded-lg p-1.5 text-left transition-colors hover:bg-bg-elevated focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus";
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";
7156
7211
  var TRACK = { gridTemplateColumns: "repeat(auto-fit, minmax(8rem, 1fr))" };
7157
- var Picker = React84.forwardRef(function Picker2({ value, onValueChange, className, ...props }, ref) {
7212
+ var Picker = React85.forwardRef(function Picker2({ value, onValueChange, className, ...props }, ref) {
7158
7213
  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) => {
7159
7214
  const selected = o.value === value;
7160
7215
  return (
@@ -7169,7 +7224,7 @@ var Picker = React84.forwardRef(function Picker2({ value, onValueChange, classNa
7169
7224
  onClick: () => onValueChange(o.value),
7170
7225
  className: cardClass,
7171
7226
  children: [
7172
- /* @__PURE__ */ jsx100("span", { className: cn(previewClass, selected && "ring-2 ring-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] }) }),
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] }) }),
7173
7228
  /* @__PURE__ */ jsxs67(
7174
7229
  "span",
7175
7230
  {
@@ -7190,7 +7245,7 @@ var Picker = React84.forwardRef(function Picker2({ value, onValueChange, classNa
7190
7245
  );
7191
7246
  }) });
7192
7247
  });
7193
- var WiredPicker = React84.forwardRef(function WiredPicker2({ onValueChange, ...props }, ref) {
7248
+ var WiredPicker = React85.forwardRef(function WiredPicker2({ onValueChange, ...props }, ref) {
7194
7249
  const { theme, setTheme } = useTheme();
7195
7250
  return /* @__PURE__ */ jsx100(
7196
7251
  Picker,
@@ -7205,8 +7260,8 @@ var WiredPicker = React84.forwardRef(function WiredPicker2({ onValueChange, ...p
7205
7260
  }
7206
7261
  );
7207
7262
  });
7208
- var ThemePicker = React84.forwardRef(function ThemePicker2({ value, onValueChange, ...props }, ref) {
7209
- const controlled = React84.useRef(value !== void 0);
7263
+ var ThemePicker = React85.forwardRef(function ThemePicker2({ value, onValueChange, ...props }, ref) {
7264
+ const controlled = React85.useRef(value !== void 0);
7210
7265
  if (process.env.NODE_ENV !== "production" && controlled.current !== (value !== void 0)) {
7211
7266
  console.warn(
7212
7267
  "[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."
@@ -7218,7 +7273,7 @@ var ThemePicker = React84.forwardRef(function ThemePicker2({ value, onValueChang
7218
7273
  ThemePicker.displayName = "ThemePicker";
7219
7274
 
7220
7275
  // src/components/secret-reveal.tsx
7221
- import * as React85 from "react";
7276
+ import * as React86 from "react";
7222
7277
  import { Copy as Copy2, Download } from "lucide-react";
7223
7278
  import { jsx as jsx101, jsxs as jsxs68 } from "react/jsx-runtime";
7224
7279
  var asText = (value) => Array.isArray(value) ? value.join("\n") : value;
@@ -7236,7 +7291,7 @@ function SecretValue({ value }) {
7236
7291
  }
7237
7292
  return /* @__PURE__ */ jsx101("code", { className: "block break-all font-mono text-sm font-medium text-text-primary", children: value });
7238
7293
  }
7239
- var SecretReveal = React85.forwardRef(
7294
+ var SecretReveal = React86.forwardRef(
7240
7295
  ({
7241
7296
  value,
7242
7297
  caption,
@@ -7253,18 +7308,18 @@ var SecretReveal = React85.forwardRef(
7253
7308
  className,
7254
7309
  ...props
7255
7310
  }, ref) => {
7256
- const [takenText, setTakenText] = React85.useState(null);
7257
- const [refusedText, setRefusedText] = React85.useState(null);
7258
- const [announcedFor, setAnnouncedFor] = React85.useState(null);
7259
- const copyRef = React85.useRef(null);
7260
- const captionId = React85.useId();
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();
7261
7316
  const text = asText(value);
7262
7317
  const empty = text.length === 0;
7263
7318
  const taken = takenText === text;
7264
7319
  const refused = refusedText === text;
7265
- React85.useEffect(() => setAnnouncedFor(text), [text]);
7320
+ React86.useEffect(() => setAnnouncedFor(text), [text]);
7266
7321
  const announced = announcedFor === text ? REVEALED : "";
7267
- React85.useEffect(() => {
7322
+ React86.useEffect(() => {
7268
7323
  if (autoFocus) copyRef.current?.focus();
7269
7324
  }, [autoFocus]);
7270
7325
  const reportTaken = () => {
@@ -7324,6 +7379,212 @@ var SecretReveal = React85.forwardRef(
7324
7379
  }
7325
7380
  );
7326
7381
  SecretReveal.displayName = "SecretReveal";
7382
+
7383
+ // src/components/star-rating.tsx
7384
+ import * as React87 from "react";
7385
+ import * as RadioGroupPrimitive2 from "@radix-ui/react-radio-group";
7386
+ import { Star } from "lucide-react";
7387
+ import { jsx as jsx102 } from "react/jsx-runtime";
7388
+ var STAR_BOX = {
7389
+ sm: "size-4",
7390
+ md: "size-5",
7391
+ lg: "size-6"
7392
+ };
7393
+ var ROW_GAP = {
7394
+ sm: "gap-0.5",
7395
+ md: "gap-1",
7396
+ lg: "gap-1.5"
7397
+ };
7398
+ var defaultItemLabel = (value, max) => `${value} out of ${max} stars`;
7399
+ var StarGlyph = ({ filled, size }) => /* @__PURE__ */ jsx102(
7400
+ Star,
7401
+ {
7402
+ "aria-hidden": "true",
7403
+ className: cn(
7404
+ STAR_BOX[size],
7405
+ "shrink-0 transition-colors duration-fast",
7406
+ filled ? "fill-current text-text-primary" : "text-text-tertiary"
7407
+ )
7408
+ }
7409
+ );
7410
+ var StarRating = React87.forwardRef(
7411
+ ({
7412
+ className,
7413
+ value,
7414
+ defaultValue,
7415
+ onValueChange,
7416
+ max = 5,
7417
+ min = 1,
7418
+ size = "md",
7419
+ readOnly,
7420
+ disabled,
7421
+ itemLabel = defaultItemLabel,
7422
+ ...props
7423
+ }, ref) => {
7424
+ const stars = Array.from({ length: max }, (_, index) => index + 1);
7425
+ const [mirror, setMirror] = React87.useState(defaultValue ?? 0);
7426
+ const selected = value ?? mirror;
7427
+ const [preview, setPreview] = React87.useState(null);
7428
+ const shown = preview ?? selected;
7429
+ const commit = (next) => {
7430
+ setMirror(next);
7431
+ onValueChange?.(next);
7432
+ };
7433
+ if (readOnly) {
7434
+ return /* @__PURE__ */ jsx102(
7435
+ "div",
7436
+ {
7437
+ ref,
7438
+ role: "img",
7439
+ "aria-label": props["aria-label"] ?? itemLabel(selected, max),
7440
+ className: cn("inline-flex items-center", ROW_GAP[size], className),
7441
+ children: stars.map((star) => /* @__PURE__ */ jsx102(StarGlyph, { filled: star <= selected, size }, star))
7442
+ }
7443
+ );
7444
+ }
7445
+ return /* @__PURE__ */ jsx102(
7446
+ RadioGroupPrimitive2.Root,
7447
+ {
7448
+ ref,
7449
+ ...props,
7450
+ disabled,
7451
+ value: String(selected),
7452
+ onValueChange: (next) => commit(Number(next)),
7453
+ onKeyDown: (event) => {
7454
+ if (min === 0 && (event.key === "Backspace" || event.key === "Delete")) {
7455
+ event.preventDefault();
7456
+ commit(0);
7457
+ }
7458
+ },
7459
+ orientation: "horizontal",
7460
+ loop: false,
7461
+ className: cn("inline-flex items-center", ROW_GAP[size], className),
7462
+ children: stars.map((star) => /* @__PURE__ */ jsx102(
7463
+ RadioGroupPrimitive2.Item,
7464
+ {
7465
+ value: String(star),
7466
+ "aria-label": itemLabel(star, max),
7467
+ onPointerEnter: () => setPreview(star),
7468
+ onPointerLeave: () => setPreview((current) => current === star ? null : current),
7469
+ onClick: () => {
7470
+ if (min === 0 && star === selected) commit(0);
7471
+ },
7472
+ className: cn(
7473
+ // Focus is an outline held off the box, never a flush ring (`Guidelines/Look/Borders`).
7474
+ "rounded-md p-0.5 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
7475
+ "disabled:pointer-events-none disabled:opacity-50"
7476
+ ),
7477
+ children: /* @__PURE__ */ jsx102(StarGlyph, { filled: star <= shown, size })
7478
+ },
7479
+ star
7480
+ ))
7481
+ }
7482
+ );
7483
+ }
7484
+ );
7485
+ StarRating.displayName = "StarRating";
7486
+
7487
+ // src/components/rating-scale.tsx
7488
+ import * as React88 from "react";
7489
+ import * as RadioGroupPrimitive3 from "@radix-ui/react-radio-group";
7490
+ import { jsx as jsx103, jsxs as jsxs69 } from "react/jsx-runtime";
7491
+ var SLOT_BOX = {
7492
+ sm: "h-8 min-w-8 px-2 text-xs",
7493
+ md: "h-9 min-w-9 px-2 text-sm",
7494
+ lg: "h-11 min-w-11 px-3 text-base"
7495
+ };
7496
+ var defaultItemLabel2 = (value, _min, max) => `${value} out of ${max}`;
7497
+ var RatingScale = React88.forwardRef(
7498
+ ({
7499
+ className,
7500
+ value,
7501
+ defaultValue,
7502
+ onValueChange,
7503
+ min = 0,
7504
+ max = 10,
7505
+ size = "md",
7506
+ readOnly,
7507
+ disabled,
7508
+ endLabels,
7509
+ itemLabel = defaultItemLabel2,
7510
+ ...props
7511
+ }, ref) => {
7512
+ const slots = Array.from({ length: Math.max(0, max - min + 1) }, (_, index) => min + index);
7513
+ const [mirror, setMirror] = React88.useState(defaultValue);
7514
+ const selected = value ?? mirror;
7515
+ const row = /* @__PURE__ */ jsx103("div", { className: cn("flex flex-wrap items-center gap-1.5", !endLabels && className), children: slots.map((slot) => {
7516
+ const isSelected = slot === selected;
7517
+ const box = cn(
7518
+ "inline-flex items-center justify-center rounded-md border tabular-nums transition-colors duration-fast",
7519
+ SLOT_BOX[size],
7520
+ isSelected ? "border-border-strong font-semibold text-text-primary" : "border-field-border font-medium text-text-secondary"
7521
+ );
7522
+ if (readOnly) {
7523
+ return /* @__PURE__ */ jsx103("span", { className: box, "aria-hidden": "true", children: slot }, slot);
7524
+ }
7525
+ return /* @__PURE__ */ jsx103(
7526
+ RadioGroupPrimitive3.Item,
7527
+ {
7528
+ value: String(slot),
7529
+ "aria-label": itemLabel(slot, min, max),
7530
+ className: cn(
7531
+ box,
7532
+ // The hover step is the same channel the mark uses, one rung short of it, so the
7533
+ // pointer never promises a mark it is not making.
7534
+ "hover:border-field-border-hover hover:text-text-primary",
7535
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
7536
+ "disabled:pointer-events-none disabled:opacity-50"
7537
+ ),
7538
+ children: slot
7539
+ },
7540
+ slot
7541
+ );
7542
+ }) });
7543
+ const ends = endLabels ? /* @__PURE__ */ jsxs69("div", { className: "flex items-center justify-between text-xs text-text-tertiary", children: [
7544
+ /* @__PURE__ */ jsx103("span", { children: endLabels.low }),
7545
+ /* @__PURE__ */ jsx103("span", { children: endLabels.high })
7546
+ ] }) : null;
7547
+ if (readOnly) {
7548
+ return /* @__PURE__ */ jsxs69(
7549
+ "div",
7550
+ {
7551
+ ref,
7552
+ role: "img",
7553
+ "aria-label": props["aria-label"] ?? (selected === void 0 ? "Not answered" : itemLabel(selected, min, max)),
7554
+ className: cn(endLabels && cn("flex flex-col gap-1.5", className)),
7555
+ children: [
7556
+ row,
7557
+ ends
7558
+ ]
7559
+ }
7560
+ );
7561
+ }
7562
+ const group = /* @__PURE__ */ jsx103(
7563
+ RadioGroupPrimitive3.Root,
7564
+ {
7565
+ ref,
7566
+ ...props,
7567
+ disabled,
7568
+ value: selected === void 0 ? "" : String(selected),
7569
+ onValueChange: (next) => {
7570
+ const parsed = Number(next);
7571
+ setMirror(parsed);
7572
+ onValueChange?.(parsed);
7573
+ },
7574
+ orientation: "horizontal",
7575
+ loop: false,
7576
+ asChild: true,
7577
+ children: row
7578
+ }
7579
+ );
7580
+ if (!endLabels) return group;
7581
+ return /* @__PURE__ */ jsxs69("div", { className: cn("flex flex-col gap-1.5", className), children: [
7582
+ group,
7583
+ ends
7584
+ ] });
7585
+ }
7586
+ );
7587
+ RatingScale.displayName = "RatingScale";
7327
7588
  export {
7328
7589
  Accordion,
7329
7590
  AccordionContent,
@@ -7538,6 +7799,7 @@ export {
7538
7799
  Progress,
7539
7800
  RadioGroup2 as RadioGroup,
7540
7801
  RadioGroupItem,
7802
+ RatingScale,
7541
7803
  RemovableChip,
7542
7804
  RemoveButton,
7543
7805
  RequestRow,
@@ -7562,6 +7824,7 @@ export {
7562
7824
  SidebarProductHeader,
7563
7825
  Skeleton,
7564
7826
  Slider,
7827
+ StarRating,
7565
7828
  StatCard,
7566
7829
  StatusDot,
7567
7830
  StepUpChallenge,
@@ -7611,6 +7874,7 @@ export {
7611
7874
  toggleVariants,
7612
7875
  useCarousel,
7613
7876
  useFormField,
7877
+ useFreshHighlight,
7614
7878
  useIsMobile,
7615
7879
  useSidebar,
7616
7880
  useTheme