@bmsuisse/ui 0.16.2 → 0.18.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
@@ -167,7 +167,7 @@ var Badge = ({ className, variant, ...props }) => /* @__PURE__ */ jsx6("div", {
167
167
 
168
168
  // src/primitives/dialog.tsx
169
169
  import * as DialogPrimitive from "@radix-ui/react-dialog";
170
- import { X } from "lucide-react";
170
+ import { XMarkIcon } from "@heroicons/react/24/outline";
171
171
  import { forwardRef as forwardRef5, useCallback, useLayoutEffect, useRef } from "react";
172
172
  import { jsx as jsx7, jsxs } from "react/jsx-runtime";
173
173
  var Dialog = DialogPrimitive.Root;
@@ -200,7 +200,7 @@ var DialogContent = forwardRef5(({ className, children, showCloseButton = true,
200
200
  "data-testid": closeButtonTestId,
201
201
  className: "absolute right-4 top-4 z-20 rounded-sm opacity-70 hover:opacity-100",
202
202
  children: [
203
- /* @__PURE__ */ jsx7(X, { className: "h-4 w-4" }),
203
+ /* @__PURE__ */ jsx7(XMarkIcon, { className: "h-4 w-4" }),
204
204
  /* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Close" })
205
205
  ]
206
206
  }
@@ -334,7 +334,7 @@ PopoverContent.displayName = "PopoverContent";
334
334
 
335
335
  // src/primitives/select.tsx
336
336
  import * as SelectPrimitive from "@radix-ui/react-select";
337
- import { Check, ChevronDown } from "lucide-react";
337
+ import { CheckIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
338
338
  import { forwardRef as forwardRef7 } from "react";
339
339
  import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
340
340
  var Select = SelectPrimitive.Root;
@@ -353,7 +353,7 @@ var SelectTrigger = forwardRef7(
353
353
  ...props,
354
354
  children: [
355
355
  children,
356
- /* @__PURE__ */ jsx9(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx9(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
356
+ /* @__PURE__ */ jsx9(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx9(ChevronDownIcon, { className: "h-4 w-4 opacity-50" }) })
357
357
  ]
358
358
  }
359
359
  )
@@ -384,7 +384,7 @@ var SelectItem = forwardRef7(({ className, children, ...props }, ref) => /* @__P
384
384
  ),
385
385
  ...props,
386
386
  children: [
387
- /* @__PURE__ */ jsx9("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx9(Check, { className: "h-4 w-4" }) }) }),
387
+ /* @__PURE__ */ jsx9("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx9(CheckIcon, { className: "h-4 w-4" }) }) }),
388
388
  /* @__PURE__ */ jsx9(SelectPrimitive.ItemText, { children })
389
389
  ]
390
390
  }
@@ -397,7 +397,7 @@ var Skeleton = ({ className, ...props }) => /* @__PURE__ */ jsx10("div", { class
397
397
 
398
398
  // src/primitives/checkbox.tsx
399
399
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
400
- import { Check as Check2 } from "lucide-react";
400
+ import { CheckIcon as CheckIcon2 } from "@heroicons/react/24/outline";
401
401
  import { forwardRef as forwardRef8 } from "react";
402
402
  import { jsx as jsx11 } from "react/jsx-runtime";
403
403
  var Checkbox = forwardRef8(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
@@ -409,7 +409,7 @@ var Checkbox = forwardRef8(({ className, ...props }, ref) => /* @__PURE__ */ jsx
409
409
  className
410
410
  ),
411
411
  ...props,
412
- children: /* @__PURE__ */ jsx11(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx11(Check2, { className: "h-3.5 w-3.5" }) })
412
+ children: /* @__PURE__ */ jsx11(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx11(CheckIcon2, { className: "h-3.5 w-3.5" }) })
413
413
  }
414
414
  ));
415
415
  Checkbox.displayName = "Checkbox";
@@ -591,7 +591,7 @@ TableCaption.displayName = "TableCaption";
591
591
 
592
592
  // src/primitives/dropdown-menu.tsx
593
593
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
594
- import { Check as Check3, ChevronRight, Circle } from "lucide-react";
594
+ import { CheckIcon as CheckIcon3, ChevronRightIcon } from "@heroicons/react/24/outline";
595
595
  import { forwardRef as forwardRef14 } from "react";
596
596
  import { jsx as jsx17, jsxs as jsxs4 } from "react/jsx-runtime";
597
597
  var DropdownMenu = DropdownMenuPrimitive.Root;
@@ -637,7 +637,7 @@ var DropdownMenuCheckboxItem = forwardRef14(({ className, children, checked, ...
637
637
  ),
638
638
  ...props,
639
639
  children: [
640
- /* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(Check3, { className: "h-4 w-4" }) }) }),
640
+ /* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(CheckIcon3, { className: "h-4 w-4" }) }) }),
641
641
  children
642
642
  ]
643
643
  }
@@ -653,7 +653,7 @@ var DropdownMenuRadioItem = forwardRef14(({ className, children, ...props }, ref
653
653
  ),
654
654
  ...props,
655
655
  children: [
656
- /* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(Circle, { className: "h-2 w-2 fill-current" }) }) }),
656
+ /* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17("span", { className: "h-2 w-2 rounded-full bg-current" }) }) }),
657
657
  children
658
658
  ]
659
659
  }
@@ -692,7 +692,7 @@ var DropdownMenuSubTrigger = forwardRef14(({ className, children, ...props }, re
692
692
  ...props,
693
693
  children: [
694
694
  children,
695
- /* @__PURE__ */ jsx17(ChevronRight, { className: "ml-auto h-4 w-4" })
695
+ /* @__PURE__ */ jsx17(ChevronRightIcon, { className: "ml-auto h-4 w-4" })
696
696
  ]
697
697
  }
698
698
  ));
@@ -713,7 +713,7 @@ DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
713
713
  // src/primitives/sheet.tsx
714
714
  import { cva as cva3 } from "class-variance-authority";
715
715
  import * as DialogPrimitive2 from "@radix-ui/react-dialog";
716
- import { X as X2 } from "lucide-react";
716
+ import { XMarkIcon as XMarkIcon2 } from "@heroicons/react/24/outline";
717
717
  import { forwardRef as forwardRef15, useEffect, useRef as useRef2, useState } from "react";
718
718
  import { jsx as jsx18, jsxs as jsxs5 } from "react/jsx-runtime";
719
719
  var Sheet = DialogPrimitive2.Root;
@@ -820,7 +820,7 @@ var SheetContent = forwardRef15(
820
820
  ),
821
821
  children,
822
822
  /* @__PURE__ */ jsxs5(DialogPrimitive2.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 hover:opacity-100", children: [
823
- /* @__PURE__ */ jsx18(X2, { className: "h-4 w-4" }),
823
+ /* @__PURE__ */ jsx18(XMarkIcon2, { className: "h-4 w-4" }),
824
824
  /* @__PURE__ */ jsx18("span", { className: "sr-only", children: "Close" })
825
825
  ] })
826
826
  ]
@@ -1356,9 +1356,104 @@ function FormField({
1356
1356
  }
1357
1357
 
1358
1358
  // src/patterns/combobox/Combobox.tsx
1359
- import { Check as Check4, ChevronsUpDown, X as X3 } from "lucide-react";
1359
+ import { CheckIcon as CheckIcon4, ChevronUpDownIcon, XMarkIcon as XMarkIcon3 } from "@heroicons/react/24/outline";
1360
1360
  import { useEffect as useEffect3, useMemo, useRef as useRef4, useState as useState8 } from "react";
1361
1361
 
1362
+ // src/lib/errorState.ts
1363
+ function toErrorInfo(error) {
1364
+ if (error == null || error === false || error === "") return void 0;
1365
+ if (typeof error === "string") return { message: error };
1366
+ if (error instanceof Error) {
1367
+ return { message: error.message || void 0, details: error.stack };
1368
+ }
1369
+ if (typeof error === "object") {
1370
+ const { title, message, details } = error;
1371
+ if (title !== void 0 || message !== void 0 || details !== void 0) return { title, message, details };
1372
+ }
1373
+ try {
1374
+ return { message: typeof error === "object" ? "Unknown error" : String(error) };
1375
+ } catch {
1376
+ return { message: "Unknown error" };
1377
+ }
1378
+ }
1379
+
1380
+ // src/patterns/error-state/ErrorState.tsx
1381
+ import { ArrowPathIcon, ExclamationTriangleIcon } from "@heroicons/react/24/outline";
1382
+ import { jsx as jsx27, jsxs as jsxs11 } from "react/jsx-runtime";
1383
+ var defaultErrorStateLabels = {
1384
+ title: "Couldn't load data",
1385
+ retry: "Retry",
1386
+ showDetails: "Show details"
1387
+ };
1388
+ var ErrorState = ({
1389
+ error,
1390
+ onRetry,
1391
+ variant = "block",
1392
+ labels,
1393
+ className,
1394
+ ...props
1395
+ }) => {
1396
+ const info = toErrorInfo(error);
1397
+ if (!info) return null;
1398
+ const l = { ...defaultErrorStateLabels, ...labels };
1399
+ const compact = variant === "compact";
1400
+ return /* @__PURE__ */ jsxs11(
1401
+ "div",
1402
+ {
1403
+ role: "alert",
1404
+ "data-testid": "error-state",
1405
+ className: cn(
1406
+ "flex gap-3 text-sm",
1407
+ compact ? "items-start rounded-md border border-destructive bg-destructive/10 p-3 text-red-800 dark:text-red-300" : "min-h-32 w-full flex-col items-center justify-center p-6 text-center",
1408
+ className
1409
+ ),
1410
+ ...props,
1411
+ children: [
1412
+ /* @__PURE__ */ jsx27(
1413
+ ExclamationTriangleIcon,
1414
+ {
1415
+ className: cn("shrink-0", compact ? "mt-0.5 h-4 w-4" : "h-8 w-8 text-destructive"),
1416
+ "aria-hidden": "true"
1417
+ }
1418
+ ),
1419
+ /* @__PURE__ */ jsxs11("div", { className: cn("flex min-w-0 flex-col gap-1", compact ? "items-start" : "items-center"), children: [
1420
+ /* @__PURE__ */ jsx27("p", { className: "font-semibold", children: info.title ?? l.title }),
1421
+ info.message ? /* @__PURE__ */ jsx27("p", { className: cn(!compact && "text-muted-foreground"), children: info.message }) : null,
1422
+ info.details ? /* @__PURE__ */ jsxs11("details", { className: "mt-1 w-full max-w-full text-left text-xs", children: [
1423
+ /* @__PURE__ */ jsx27("summary", { className: "cursor-pointer select-none underline underline-offset-2", children: l.showDetails }),
1424
+ /* @__PURE__ */ jsx27("pre", { className: "mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-words rounded bg-muted p-2 text-muted-foreground", children: info.details })
1425
+ ] }) : null,
1426
+ onRetry ? /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "outline", size: "sm", className: "mt-2", onClick: onRetry, children: [
1427
+ /* @__PURE__ */ jsx27(ArrowPathIcon, { className: "h-4 w-4", "aria-hidden": "true" }),
1428
+ l.retry
1429
+ ] }) : null
1430
+ ] })
1431
+ ]
1432
+ }
1433
+ );
1434
+ };
1435
+ var InlineError = ({ error, onRetry, labels, className, ...props }) => {
1436
+ const info = toErrorInfo(error);
1437
+ if (!info) return null;
1438
+ const l = { ...defaultErrorStateLabels, ...labels };
1439
+ const text = info.message ?? info.title ?? l.title;
1440
+ return /* @__PURE__ */ jsxs11(
1441
+ "span",
1442
+ {
1443
+ role: "alert",
1444
+ "data-testid": "inline-error",
1445
+ title: info.details,
1446
+ className: cn("inline-flex min-w-0 items-center gap-1.5 text-xs text-red-700 dark:text-red-300", className),
1447
+ ...props,
1448
+ children: [
1449
+ /* @__PURE__ */ jsx27(ExclamationTriangleIcon, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }),
1450
+ /* @__PURE__ */ jsx27("span", { className: "truncate", children: text }),
1451
+ onRetry ? /* @__PURE__ */ jsx27("button", { type: "button", className: "shrink-0 underline underline-offset-2", onClick: onRetry, children: l.retry }) : null
1452
+ ]
1453
+ }
1454
+ );
1455
+ };
1456
+
1362
1457
  // src/lib/optionGrouping.ts
1363
1458
  function groupMembers(options, group) {
1364
1459
  return options.filter((o) => o.group === group && !o.disabled).map((o) => o.value);
@@ -1386,7 +1481,7 @@ function buildRenderChunks(visibleOptions) {
1386
1481
  }
1387
1482
 
1388
1483
  // src/lib/optionGrid.tsx
1389
- import { jsx as jsx27, jsxs as jsxs11 } from "react/jsx-runtime";
1484
+ import { jsx as jsx28, jsxs as jsxs12 } from "react/jsx-runtime";
1390
1485
  function renderGridOptions({
1391
1486
  columns,
1392
1487
  options,
@@ -1397,10 +1492,10 @@ function renderGridOptions({
1397
1492
  onHover,
1398
1493
  testId
1399
1494
  }) {
1400
- return /* @__PURE__ */ jsxs11(Table, { className: "text-sm", children: [
1401
- /* @__PURE__ */ jsx27(TableHeader, { children: /* @__PURE__ */ jsxs11(TableRow, { className: "hover:bg-transparent", children: [
1402
- multiple && /* @__PURE__ */ jsx27(TableHead, { className: "sticky top-0 z-10 w-6 bg-muted" }),
1403
- columns.map((column) => /* @__PURE__ */ jsx27(
1495
+ return /* @__PURE__ */ jsxs12(Table, { className: "text-sm", children: [
1496
+ /* @__PURE__ */ jsx28(TableHeader, { children: /* @__PURE__ */ jsxs12(TableRow, { className: "hover:bg-transparent", children: [
1497
+ multiple && /* @__PURE__ */ jsx28(TableHead, { className: "sticky top-0 z-10 w-6 bg-muted" }),
1498
+ columns.map((column) => /* @__PURE__ */ jsx28(
1404
1499
  TableHead,
1405
1500
  {
1406
1501
  className: cn("sticky top-0 z-10 whitespace-nowrap bg-muted text-xs", column.className),
@@ -1409,10 +1504,10 @@ function renderGridOptions({
1409
1504
  column.key
1410
1505
  ))
1411
1506
  ] }) }),
1412
- /* @__PURE__ */ jsx27(TableBody, { children: options.map((option, index) => {
1507
+ /* @__PURE__ */ jsx28(TableBody, { children: options.map((option, index) => {
1413
1508
  const selected = isSelected(option);
1414
1509
  const active = index === activeIndex;
1415
- return /* @__PURE__ */ jsxs11(
1510
+ return /* @__PURE__ */ jsxs12(
1416
1511
  TableRow,
1417
1512
  {
1418
1513
  role: "option",
@@ -1436,7 +1531,7 @@ function renderGridOptions({
1436
1531
  option.disabled && "pointer-events-none opacity-50"
1437
1532
  ),
1438
1533
  children: [
1439
- multiple && /* @__PURE__ */ jsx27(TableCell, { className: "w-6", children: /* @__PURE__ */ jsx27(
1534
+ multiple && /* @__PURE__ */ jsx28(TableCell, { className: "w-6", children: /* @__PURE__ */ jsx28(
1440
1535
  "input",
1441
1536
  {
1442
1537
  type: "checkbox",
@@ -1446,7 +1541,7 @@ function renderGridOptions({
1446
1541
  className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
1447
1542
  }
1448
1543
  ) }),
1449
- columns.map((column) => /* @__PURE__ */ jsx27(TableCell, { className: cn("truncate", column.className), children: column.key === "label" ? option.label : option.data?.[column.key] }, column.key))
1544
+ columns.map((column) => /* @__PURE__ */ jsx28(TableCell, { className: cn("truncate", column.className), children: column.key === "label" ? option.label : option.data?.[column.key] }, column.key))
1450
1545
  ]
1451
1546
  },
1452
1547
  option.value
@@ -1456,7 +1551,7 @@ function renderGridOptions({
1456
1551
  }
1457
1552
 
1458
1553
  // src/patterns/combobox/Combobox.tsx
1459
- import { jsx as jsx28, jsxs as jsxs12 } from "react/jsx-runtime";
1554
+ import { jsx as jsx29, jsxs as jsxs13 } from "react/jsx-runtime";
1460
1555
  function resolveGroupTriggerLabel(options, selectedValues, groupLabel) {
1461
1556
  const selectedSet = new Set(selectedValues);
1462
1557
  const groupsPresent = Array.from(
@@ -1485,6 +1580,8 @@ function Combobox(props) {
1485
1580
  disabled,
1486
1581
  loading = false,
1487
1582
  loadingMessage = "Loading\u2026",
1583
+ error,
1584
+ onRetry,
1488
1585
  clearable = true,
1489
1586
  className,
1490
1587
  id,
@@ -1495,6 +1592,7 @@ function Combobox(props) {
1495
1592
  columns
1496
1593
  } = props;
1497
1594
  const testId = props["data-testid"];
1595
+ const hasError = toErrorInfo(error) !== void 0;
1498
1596
  const [open, setOpen] = useState8(false);
1499
1597
  const [search, setSearch] = useState8("");
1500
1598
  const [activeIndex, setActiveIndex] = useState8(0);
@@ -1536,6 +1634,7 @@ function Combobox(props) {
1536
1634
  setOpen(false);
1537
1635
  }
1538
1636
  function handleKeyDown(event) {
1637
+ if (hasError) return;
1539
1638
  if (event.key === "ArrowDown") {
1540
1639
  event.preventDefault();
1541
1640
  setActiveIndex((i) => Math.min(i + 1, visibleOptions.length - 1));
@@ -1560,7 +1659,7 @@ function Combobox(props) {
1560
1659
  function renderOption({ option, index }) {
1561
1660
  const isSelected = selectedValues.includes(option.value);
1562
1661
  const isActive = index === activeIndex;
1563
- return /* @__PURE__ */ jsxs12(
1662
+ return /* @__PURE__ */ jsxs13(
1564
1663
  "button",
1565
1664
  {
1566
1665
  type: "button",
@@ -1576,7 +1675,7 @@ function Combobox(props) {
1576
1675
  isActive && "bg-accent text-accent-foreground"
1577
1676
  ),
1578
1677
  children: [
1579
- props.multiple ? /* @__PURE__ */ jsx28(
1678
+ props.multiple ? /* @__PURE__ */ jsx29(
1580
1679
  "input",
1581
1680
  {
1582
1681
  type: "checkbox",
@@ -1585,15 +1684,15 @@ function Combobox(props) {
1585
1684
  tabIndex: -1,
1586
1685
  className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
1587
1686
  }
1588
- ) : /* @__PURE__ */ jsx28(Check4, { className: cn("h-4 w-4 shrink-0", isSelected ? "opacity-100" : "opacity-0") }),
1589
- /* @__PURE__ */ jsx28("span", { className: "truncate", children: option.label })
1687
+ ) : /* @__PURE__ */ jsx29(CheckIcon4, { className: cn("h-4 w-4 shrink-0", isSelected ? "opacity-100" : "opacity-0") }),
1688
+ /* @__PURE__ */ jsx29("span", { className: "truncate", children: option.label })
1590
1689
  ]
1591
1690
  },
1592
1691
  option.value
1593
1692
  );
1594
1693
  }
1595
- return /* @__PURE__ */ jsxs12(Popover, { open, onOpenChange: setOpen, children: [
1596
- /* @__PURE__ */ jsx28(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs12(
1694
+ return /* @__PURE__ */ jsxs13(Popover, { open, onOpenChange: setOpen, children: [
1695
+ /* @__PURE__ */ jsx29(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs13(
1597
1696
  Button,
1598
1697
  {
1599
1698
  id,
@@ -1602,16 +1701,18 @@ function Combobox(props) {
1602
1701
  variant: "outline",
1603
1702
  role: "combobox",
1604
1703
  "aria-expanded": open,
1704
+ "aria-invalid": hasError || void 0,
1605
1705
  disabled: disabled || loading,
1606
1706
  className: cn(
1607
1707
  "w-full justify-between font-normal",
1708
+ hasError && "border-destructive",
1608
1709
  (selectedOptions.length === 0 || loading) && "text-muted-foreground",
1609
1710
  className
1610
1711
  ),
1611
1712
  children: [
1612
- /* @__PURE__ */ jsx28("span", { className: "truncate", children: triggerLabel }),
1613
- /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1", children: [
1614
- clearable && !loading && selectedValues.length > 0 ? /* @__PURE__ */ jsx28(
1713
+ /* @__PURE__ */ jsx29("span", { className: "truncate", children: triggerLabel }),
1714
+ /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-1", children: [
1715
+ clearable && !loading && selectedValues.length > 0 ? /* @__PURE__ */ jsx29(
1615
1716
  "span",
1616
1717
  {
1617
1718
  role: "button",
@@ -1626,15 +1727,15 @@ function Combobox(props) {
1626
1727
  props.onChange(null);
1627
1728
  }
1628
1729
  },
1629
- children: /* @__PURE__ */ jsx28(X3, { className: "h-3.5 w-3.5" })
1730
+ children: /* @__PURE__ */ jsx29(XMarkIcon3, { className: "h-3.5 w-3.5" })
1630
1731
  }
1631
1732
  ) : null,
1632
- /* @__PURE__ */ jsx28(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50", "aria-hidden": "true" })
1733
+ /* @__PURE__ */ jsx29(ChevronUpDownIcon, { className: "h-4 w-4 shrink-0 opacity-50", "aria-hidden": "true" })
1633
1734
  ] })
1634
1735
  ]
1635
1736
  }
1636
1737
  ) }),
1637
- /* @__PURE__ */ jsx28(
1738
+ /* @__PURE__ */ jsx29(
1638
1739
  PopoverContent,
1639
1740
  {
1640
1741
  align: "start",
@@ -1644,8 +1745,8 @@ function Combobox(props) {
1644
1745
  columns && "w-max min-w-[var(--radix-popover-trigger-width)] max-w-[min(40rem,90vw)]"
1645
1746
  ),
1646
1747
  onOpenAutoFocus: (event) => event.preventDefault(),
1647
- children: /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-2", children: [
1648
- /* @__PURE__ */ jsx28(
1748
+ children: /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
1749
+ /* @__PURE__ */ jsx29(
1649
1750
  Input,
1650
1751
  {
1651
1752
  ref: inputRef,
@@ -1659,7 +1760,7 @@ function Combobox(props) {
1659
1760
  "aria-label": searchPlaceholder
1660
1761
  }
1661
1762
  ),
1662
- /* @__PURE__ */ jsx28("div", { role: "listbox", className: cn("max-h-60 overflow-y-auto", !columns && "flex flex-col gap-0.5"), children: visibleOptions.length === 0 ? /* @__PURE__ */ jsx28("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : columns ? renderGridOptions({
1763
+ /* @__PURE__ */ jsx29("div", { role: hasError ? void 0 : "listbox", className: cn("max-h-60 overflow-y-auto", !columns && "flex flex-col gap-0.5"), children: hasError ? /* @__PURE__ */ jsx29("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsx29(InlineError, { error, onRetry }) }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx29("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : columns ? renderGridOptions({
1663
1764
  columns,
1664
1765
  options: visibleOptions,
1665
1766
  activeIndex,
@@ -1679,14 +1780,14 @@ function Combobox(props) {
1679
1780
  // lives on this wrapper's `pt-1`, not on the header itself -- a margin on
1680
1781
  // the sticky element would travel with it once stuck, leaving a gap at the
1681
1782
  // scrollport's top that the row behind it shows through.
1682
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-0.5 pt-1 first:pt-0", children: [
1683
- /* @__PURE__ */ jsxs12(
1783
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-0.5 pt-1 first:pt-0", children: [
1784
+ /* @__PURE__ */ jsxs13(
1684
1785
  "div",
1685
1786
  {
1686
1787
  "data-group-header": true,
1687
1788
  className: "sticky top-0 z-10 flex items-center gap-2 rounded-sm bg-muted px-2 py-1.5 text-sm font-semibold text-foreground",
1688
1789
  children: [
1689
- props.multiple ? /* @__PURE__ */ jsx28(
1790
+ props.multiple ? /* @__PURE__ */ jsx29(
1690
1791
  "input",
1691
1792
  {
1692
1793
  type: "checkbox",
@@ -1700,7 +1801,7 @@ function Combobox(props) {
1700
1801
  "aria-label": `Select all of ${groupLabel(chunk.group)}`
1701
1802
  }
1702
1803
  ) : null,
1703
- /* @__PURE__ */ jsx28("span", { className: "truncate", children: groupLabel(chunk.group) })
1804
+ /* @__PURE__ */ jsx29("span", { className: "truncate", children: groupLabel(chunk.group) })
1704
1805
  ]
1705
1806
  }
1706
1807
  ),
@@ -1715,9 +1816,9 @@ function Combobox(props) {
1715
1816
  }
1716
1817
 
1717
1818
  // src/patterns/tag-combobox/TagCombobox.tsx
1718
- import { X as X4 } from "lucide-react";
1819
+ import { XMarkIcon as XMarkIcon4 } from "@heroicons/react/24/outline";
1719
1820
  import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState9 } from "react";
1720
- import { jsx as jsx29, jsxs as jsxs13 } from "react/jsx-runtime";
1821
+ import { jsx as jsx30, jsxs as jsxs14 } from "react/jsx-runtime";
1721
1822
  function TagCombobox({
1722
1823
  options,
1723
1824
  value,
@@ -1727,6 +1828,8 @@ function TagCombobox({
1727
1828
  disabled,
1728
1829
  loading = false,
1729
1830
  loadingMessage = "Loading\u2026",
1831
+ error,
1832
+ onRetry,
1730
1833
  className,
1731
1834
  id,
1732
1835
  onSearchChange,
@@ -1786,6 +1889,7 @@ function TagCombobox({
1786
1889
  onChange(next);
1787
1890
  inputRef.current?.focus();
1788
1891
  }
1892
+ const hasError = toErrorInfo(error) !== void 0;
1789
1893
  function handleKeyDown(event) {
1790
1894
  if (event.key === "ArrowDown") {
1791
1895
  event.preventDefault();
@@ -1797,7 +1901,7 @@ function TagCombobox({
1797
1901
  } else if (event.key === "Enter") {
1798
1902
  event.preventDefault();
1799
1903
  const option = visibleOptions[activeIndex];
1800
- if (option) toggleOption(option);
1904
+ if (option && !hasError) toggleOption(option);
1801
1905
  } else if (event.key === "Escape") {
1802
1906
  setOpen(false);
1803
1907
  } else if (event.key === "Backspace" && search === "") {
@@ -1808,7 +1912,7 @@ function TagCombobox({
1808
1912
  function renderOption({ option, index }) {
1809
1913
  const isSelected = value.includes(option.value);
1810
1914
  const isActive = index === activeIndex;
1811
- return /* @__PURE__ */ jsxs13(
1915
+ return /* @__PURE__ */ jsxs14(
1812
1916
  "button",
1813
1917
  {
1814
1918
  type: "button",
@@ -1824,7 +1928,7 @@ function TagCombobox({
1824
1928
  isActive && "bg-accent text-accent-foreground"
1825
1929
  ),
1826
1930
  children: [
1827
- /* @__PURE__ */ jsx29(
1931
+ /* @__PURE__ */ jsx30(
1828
1932
  "input",
1829
1933
  {
1830
1934
  type: "checkbox",
@@ -1834,14 +1938,14 @@ function TagCombobox({
1834
1938
  className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
1835
1939
  }
1836
1940
  ),
1837
- /* @__PURE__ */ jsx29("span", { className: "truncate", children: option.label })
1941
+ /* @__PURE__ */ jsx30("span", { className: "truncate", children: option.label })
1838
1942
  ]
1839
1943
  },
1840
1944
  option.value
1841
1945
  );
1842
1946
  }
1843
- return /* @__PURE__ */ jsxs13(Popover, { open, onOpenChange: setOpen, children: [
1844
- /* @__PURE__ */ jsx29(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs13(
1947
+ return /* @__PURE__ */ jsxs14(Popover, { open, onOpenChange: setOpen, children: [
1948
+ /* @__PURE__ */ jsx30(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs14(
1845
1949
  "div",
1846
1950
  {
1847
1951
  ref: fieldRef,
@@ -1859,13 +1963,13 @@ function TagCombobox({
1859
1963
  if (!disabled) inputRef.current?.focus();
1860
1964
  },
1861
1965
  children: [
1862
- selectedOptions.map((option) => /* @__PURE__ */ jsxs13(
1966
+ selectedOptions.map((option) => /* @__PURE__ */ jsxs14(
1863
1967
  "span",
1864
1968
  {
1865
1969
  className: "inline-flex items-center gap-1 rounded-full bg-muted py-0.5 pr-1 pl-2.5 text-xs font-medium text-muted-foreground",
1866
1970
  children: [
1867
- /* @__PURE__ */ jsx29("span", { className: "max-w-48 truncate", children: option.label }),
1868
- !disabled && /* @__PURE__ */ jsx29(
1971
+ /* @__PURE__ */ jsx30("span", { className: "max-w-48 truncate", children: option.label }),
1972
+ !disabled && /* @__PURE__ */ jsx30(
1869
1973
  "button",
1870
1974
  {
1871
1975
  type: "button",
@@ -1875,14 +1979,14 @@ function TagCombobox({
1875
1979
  event.stopPropagation();
1876
1980
  removeValue(option.value);
1877
1981
  },
1878
- children: /* @__PURE__ */ jsx29(X4, { className: "h-3 w-3" })
1982
+ children: /* @__PURE__ */ jsx30(XMarkIcon4, { className: "h-3 w-3" })
1879
1983
  }
1880
1984
  )
1881
1985
  ]
1882
1986
  },
1883
1987
  option.value
1884
1988
  )),
1885
- /* @__PURE__ */ jsx29(
1989
+ /* @__PURE__ */ jsx30(
1886
1990
  "input",
1887
1991
  {
1888
1992
  ref: inputRef,
@@ -1900,7 +2004,7 @@ function TagCombobox({
1900
2004
  ]
1901
2005
  }
1902
2006
  ) }),
1903
- /* @__PURE__ */ jsx29(
2007
+ /* @__PURE__ */ jsx30(
1904
2008
  PopoverContent,
1905
2009
  {
1906
2010
  align: "start",
@@ -1914,7 +2018,7 @@ function TagCombobox({
1914
2018
  onInteractOutside: (event) => {
1915
2019
  if (fieldRef.current?.contains(event.target)) event.preventDefault();
1916
2020
  },
1917
- children: /* @__PURE__ */ jsx29("div", { role: "listbox", className: cn("max-h-60 overflow-y-auto", !columns && "flex flex-col gap-0.5"), children: loading ? /* @__PURE__ */ jsx29("p", { className: "py-2 text-center text-sm text-muted-foreground", children: loadingMessage }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx29("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : columns ? renderGridOptions({
2021
+ children: /* @__PURE__ */ jsx30("div", { role: hasError ? void 0 : "listbox", className: cn("max-h-60 overflow-y-auto", !columns && "flex flex-col gap-0.5"), children: loading ? /* @__PURE__ */ jsx30("p", { className: "py-2 text-center text-sm text-muted-foreground", children: loadingMessage }) : hasError ? /* @__PURE__ */ jsx30("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsx30(InlineError, { error, onRetry }) }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx30("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : columns ? renderGridOptions({
1918
2022
  columns,
1919
2023
  options: visibleOptions,
1920
2024
  activeIndex,
@@ -1933,14 +2037,14 @@ function TagCombobox({
1933
2037
  // past its first row. Spacing above a group lives on this wrapper's
1934
2038
  // `pt-1`/`first:pt-0`, not on the header itself -- see `Combobox`'s own
1935
2039
  // identical structure for why both of these matter.
1936
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-0.5 pt-1 first:pt-0", children: [
1937
- /* @__PURE__ */ jsxs13(
2040
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-0.5 pt-1 first:pt-0", children: [
2041
+ /* @__PURE__ */ jsxs14(
1938
2042
  "div",
1939
2043
  {
1940
2044
  "data-group-header": true,
1941
2045
  className: "sticky top-0 z-10 flex items-center gap-2 rounded-sm bg-muted px-2 py-1.5 text-sm font-semibold text-foreground",
1942
2046
  children: [
1943
- /* @__PURE__ */ jsx29(
2047
+ /* @__PURE__ */ jsx30(
1944
2048
  "input",
1945
2049
  {
1946
2050
  type: "checkbox",
@@ -1954,7 +2058,7 @@ function TagCombobox({
1954
2058
  "aria-label": `Select all of ${groupLabel(chunk.group)}`
1955
2059
  }
1956
2060
  ),
1957
- /* @__PURE__ */ jsx29("span", { className: "truncate", children: groupLabel(chunk.group) })
2061
+ /* @__PURE__ */ jsx30("span", { className: "truncate", children: groupLabel(chunk.group) })
1958
2062
  ]
1959
2063
  }
1960
2064
  ),
@@ -1968,8 +2072,13 @@ function TagCombobox({
1968
2072
  }
1969
2073
 
1970
2074
  // src/patterns/alert-box/AlertBox.tsx
1971
- import { AlertCircle, AlertTriangle, CheckCircle2, Info } from "lucide-react";
1972
- import { jsx as jsx30, jsxs as jsxs14 } from "react/jsx-runtime";
2075
+ import {
2076
+ CheckCircleIcon,
2077
+ ExclamationCircleIcon,
2078
+ ExclamationTriangleIcon as ExclamationTriangleIcon2,
2079
+ InformationCircleIcon
2080
+ } from "@heroicons/react/24/outline";
2081
+ import { jsx as jsx31, jsxs as jsxs15 } from "react/jsx-runtime";
1973
2082
  var variantStyles = {
1974
2083
  error: "border-destructive bg-destructive/10 text-red-800 dark:text-red-300",
1975
2084
  warning: "border-amber-500 bg-amber-500/10 text-amber-900 dark:text-amber-200",
@@ -1977,24 +2086,24 @@ var variantStyles = {
1977
2086
  success: "border-emerald-500 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"
1978
2087
  };
1979
2088
  var defaultIcons = {
1980
- error: /* @__PURE__ */ jsx30(AlertCircle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
1981
- warning: /* @__PURE__ */ jsx30(AlertTriangle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
1982
- info: /* @__PURE__ */ jsx30(Info, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
1983
- success: /* @__PURE__ */ jsx30(CheckCircle2, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" })
2089
+ error: /* @__PURE__ */ jsx31(ExclamationCircleIcon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
2090
+ warning: /* @__PURE__ */ jsx31(ExclamationTriangleIcon2, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
2091
+ info: /* @__PURE__ */ jsx31(InformationCircleIcon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
2092
+ success: /* @__PURE__ */ jsx31(CheckCircleIcon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" })
1984
2093
  };
1985
2094
  var AlertBox = ({ variant, title, children, className, icon }) => {
1986
2095
  const resolvedIcon = icon === void 0 ? defaultIcons[variant] : icon;
1987
- return /* @__PURE__ */ jsx30("div", { className: cn("rounded-md border p-3 text-sm", variantStyles[variant], className), children: /* @__PURE__ */ jsxs14("div", { className: "flex flex-row items-start gap-2", children: [
1988
- resolvedIcon != null && /* @__PURE__ */ jsx30("span", { className: "mt-0.5 shrink-0", children: resolvedIcon }),
1989
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
1990
- title && /* @__PURE__ */ jsx30("p", { className: "font-bold", children: title }),
1991
- /* @__PURE__ */ jsx30("div", { children })
2096
+ return /* @__PURE__ */ jsx31("div", { className: cn("rounded-md border p-3 text-sm", variantStyles[variant], className), children: /* @__PURE__ */ jsxs15("div", { className: "flex flex-row items-start gap-2", children: [
2097
+ resolvedIcon != null && /* @__PURE__ */ jsx31("span", { className: "mt-0.5 shrink-0", children: resolvedIcon }),
2098
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
2099
+ title && /* @__PURE__ */ jsx31("p", { className: "font-bold", children: title }),
2100
+ /* @__PURE__ */ jsx31("div", { children })
1992
2101
  ] })
1993
2102
  ] }) });
1994
2103
  };
1995
2104
 
1996
2105
  // src/patterns/status-badge/StatusBadge.tsx
1997
- import { jsx as jsx31 } from "react/jsx-runtime";
2106
+ import { jsx as jsx32 } from "react/jsx-runtime";
1998
2107
  var TONE_CLASSES = {
1999
2108
  success: "border-transparent bg-emerald-500/15 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-300",
2000
2109
  warning: "border-transparent bg-amber-500/15 text-amber-800 dark:bg-amber-500/20 dark:text-amber-300",
@@ -2041,11 +2150,11 @@ function resolveTone(status, tone, toneMap) {
2041
2150
  var StatusBadge = ({ status, label, tone, toneMap, className, ...props }) => {
2042
2151
  const resolvedTone = resolveTone(status, tone, toneMap);
2043
2152
  const displayLabel = label ?? deriveLabel(status);
2044
- return /* @__PURE__ */ jsx31(Badge, { variant: "outline", className: cn(TONE_CLASSES[resolvedTone], className), ...props, children: displayLabel });
2153
+ return /* @__PURE__ */ jsx32(Badge, { variant: "outline", className: cn(TONE_CLASSES[resolvedTone], className), ...props, children: displayLabel });
2045
2154
  };
2046
2155
 
2047
2156
  // src/patterns/button-group/ButtonGroup.tsx
2048
- import { jsx as jsx32, jsxs as jsxs15 } from "react/jsx-runtime";
2157
+ import { jsx as jsx33, jsxs as jsxs16 } from "react/jsx-runtime";
2049
2158
  function ButtonGroup({
2050
2159
  options,
2051
2160
  value,
@@ -2055,10 +2164,10 @@ function ButtonGroup({
2055
2164
  className,
2056
2165
  ...props
2057
2166
  }) {
2058
- return /* @__PURE__ */ jsx32("div", { role: "group", "aria-label": props["aria-label"], className: cn("inline-flex", className), "data-testid": props["data-testid"], children: options.map((option, index) => {
2167
+ return /* @__PURE__ */ jsx33("div", { role: "group", "aria-label": props["aria-label"], className: cn("inline-flex", className), "data-testid": props["data-testid"], children: options.map((option, index) => {
2059
2168
  const selected = option.value === value;
2060
2169
  const Icon2 = option.icon;
2061
- return /* @__PURE__ */ jsxs15(
2170
+ return /* @__PURE__ */ jsxs16(
2062
2171
  Button,
2063
2172
  {
2064
2173
  type: "button",
@@ -2076,7 +2185,7 @@ function ButtonGroup({
2076
2185
  index > 0 && "-ml-px"
2077
2186
  ),
2078
2187
  children: [
2079
- Icon2 && /* @__PURE__ */ jsx32(Icon2, { className: "h-4 w-4" }),
2188
+ Icon2 && /* @__PURE__ */ jsx33(Icon2, { className: "h-4 w-4" }),
2080
2189
  option.label
2081
2190
  ]
2082
2191
  },
@@ -2087,8 +2196,8 @@ function ButtonGroup({
2087
2196
 
2088
2197
  // src/patterns/loading-spinner/LoadingSpinner.tsx
2089
2198
  import { cva as cva4 } from "class-variance-authority";
2090
- import { Loader2 } from "lucide-react";
2091
- import { jsx as jsx33, jsxs as jsxs16 } from "react/jsx-runtime";
2199
+ import { ArrowPathIcon as ArrowPathIcon2 } from "@heroicons/react/24/outline";
2200
+ import { jsx as jsx34, jsxs as jsxs17 } from "react/jsx-runtime";
2092
2201
  var loadingSpinnerIconVariants = cva4("animate-spin text-muted-foreground", {
2093
2202
  variants: {
2094
2203
  size: {
@@ -2106,75 +2215,167 @@ var LoadingSpinner = ({
2106
2215
  label,
2107
2216
  className,
2108
2217
  ...props
2109
- }) => /* @__PURE__ */ jsxs16("span", { role: "status", className: cn("inline-flex items-center gap-2", className), ...props, children: [
2110
- /* @__PURE__ */ jsx33(Loader2, { className: cn(loadingSpinnerIconVariants({ size })), "aria-hidden": "true" }),
2111
- label ? /* @__PURE__ */ jsx33("span", { children: label }) : null
2218
+ }) => /* @__PURE__ */ jsxs17("span", { role: "status", className: cn("inline-flex items-center gap-2", className), ...props, children: [
2219
+ /* @__PURE__ */ jsx34(ArrowPathIcon2, { className: cn(loadingSpinnerIconVariants({ size })), "aria-hidden": "true" }),
2220
+ label ? /* @__PURE__ */ jsx34("span", { children: label }) : null
2112
2221
  ] });
2113
2222
  var LoadingOverlay = ({
2114
2223
  size = "lg",
2115
2224
  label,
2116
2225
  className,
2117
2226
  ...props
2118
- }) => /* @__PURE__ */ jsx33(
2227
+ }) => /* @__PURE__ */ jsx34(
2119
2228
  "div",
2120
2229
  {
2121
2230
  className: cn("flex h-full min-h-32 w-full items-center justify-center", className),
2122
2231
  ...props,
2123
- children: /* @__PURE__ */ jsx33(LoadingSpinner, { size, label })
2232
+ children: /* @__PURE__ */ jsx34(LoadingSpinner, { size, label })
2124
2233
  }
2125
2234
  );
2126
2235
 
2236
+ // src/patterns/loading-spinner/LoadingState.tsx
2237
+ import { useEffect as useEffect5, useState as useState10 } from "react";
2238
+ import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
2239
+ function useDelayedFlag(active, delayMs = 150) {
2240
+ const [shown, setShown] = useState10(false);
2241
+ useEffect5(() => {
2242
+ if (!active) {
2243
+ setShown(false);
2244
+ return;
2245
+ }
2246
+ if (delayMs <= 0) {
2247
+ setShown(true);
2248
+ return;
2249
+ }
2250
+ const timer = setTimeout(() => setShown(true), delayMs);
2251
+ return () => clearTimeout(timer);
2252
+ }, [active, delayMs]);
2253
+ return active && (delayMs <= 0 || shown);
2254
+ }
2255
+ var LoadingState = ({
2256
+ variant = "skeleton",
2257
+ lines = 3,
2258
+ label = "Loading\u2026",
2259
+ delayMs = 150,
2260
+ className,
2261
+ ...props
2262
+ }) => {
2263
+ const visible = useDelayedFlag(true, delayMs);
2264
+ if (variant === "spinner") {
2265
+ return /* @__PURE__ */ jsx35("div", { "data-testid": "loading-state", "aria-busy": "true", className: cn(!visible && "invisible", className), ...props, children: /* @__PURE__ */ jsx35(LoadingOverlay, { label }) });
2266
+ }
2267
+ return /* @__PURE__ */ jsxs18(
2268
+ "div",
2269
+ {
2270
+ role: "status",
2271
+ "aria-busy": "true",
2272
+ "data-testid": "loading-state",
2273
+ className: cn("flex w-full flex-col gap-2 p-1", !visible && "invisible", className),
2274
+ ...props,
2275
+ children: [
2276
+ /* @__PURE__ */ jsx35("span", { className: "sr-only", children: label }),
2277
+ Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx35(Skeleton, { "aria-hidden": "true", className: cn("h-4", i === lines - 1 && lines > 1 ? "w-2/3" : "w-full") }, i))
2278
+ ]
2279
+ }
2280
+ );
2281
+ };
2282
+ var RefreshBar = ({ active, className }) => active ? /* @__PURE__ */ jsx35(
2283
+ "div",
2284
+ {
2285
+ role: "progressbar",
2286
+ "aria-label": "Refreshing",
2287
+ "data-testid": "refresh-bar",
2288
+ className: cn("absolute inset-x-0 top-0 z-30 h-0.5 overflow-hidden bg-muted", className),
2289
+ children: /* @__PURE__ */ jsx35("div", { className: "h-full w-1/3 animate-pulse bg-primary motion-reduce:animate-none" })
2290
+ }
2291
+ ) : null;
2292
+
2293
+ // src/patterns/async-boundary/AsyncBoundary.tsx
2294
+ import { Fragment as Fragment3, jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
2295
+ var AsyncBoundary = ({
2296
+ loading = false,
2297
+ error,
2298
+ onRetry,
2299
+ empty = false,
2300
+ emptyContent,
2301
+ loadingContent,
2302
+ hasData,
2303
+ children
2304
+ }) => {
2305
+ const failed = toErrorInfo(error) !== void 0;
2306
+ const showData = hasData ?? false;
2307
+ if (loading && !showData) return /* @__PURE__ */ jsx36(Fragment3, { children: loadingContent ?? /* @__PURE__ */ jsx36(LoadingState, {}) });
2308
+ if (failed && !showData) return /* @__PURE__ */ jsx36(ErrorState, { error, onRetry });
2309
+ if (empty && !showData) return /* @__PURE__ */ jsx36(Fragment3, { children: emptyContent ?? null });
2310
+ return /* @__PURE__ */ jsxs19("div", { className: "relative", children: [
2311
+ /* @__PURE__ */ jsx36(RefreshBar, { active: loading }),
2312
+ failed ? /* @__PURE__ */ jsx36(InlineError, { error, onRetry, className: "mb-2" }) : null,
2313
+ children
2314
+ ] });
2315
+ };
2316
+
2127
2317
  // src/patterns/search-bar/SearchBar.tsx
2128
- import { Search, X as X5 } from "lucide-react";
2129
- import { jsx as jsx34, jsxs as jsxs17 } from "react/jsx-runtime";
2318
+ import { ExclamationTriangleIcon as ExclamationTriangleIcon3, MagnifyingGlassIcon, XMarkIcon as XMarkIcon5 } from "@heroicons/react/24/outline";
2319
+ import { jsx as jsx37, jsxs as jsxs20 } from "react/jsx-runtime";
2130
2320
  function SearchBar({
2131
2321
  value,
2132
2322
  onChange,
2323
+ loading,
2133
2324
  isLoading,
2325
+ error,
2326
+ onRetry,
2134
2327
  onClear,
2135
2328
  clearLabel = "Clear search",
2136
2329
  inputRef,
2137
2330
  className,
2138
2331
  ...props
2139
2332
  }) {
2333
+ const busy = loading ?? isLoading;
2334
+ const hasError = toErrorInfo(error) !== void 0;
2140
2335
  const showClear = onClear !== false && value.length > 0;
2141
- return /* @__PURE__ */ jsxs17("div", { className: cn("relative", className), children: [
2142
- /* @__PURE__ */ jsx34("span", { className: "pointer-events-none absolute top-1/2 left-4 -translate-y-1/2 text-muted-foreground", children: isLoading ? /* @__PURE__ */ jsx34(LoadingSpinner, { size: "sm" }) : /* @__PURE__ */ jsx34(Search, { className: "h-4 w-4", "aria-hidden": "true" }) }),
2143
- /* @__PURE__ */ jsx34(
2144
- "input",
2145
- {
2146
- ref: inputRef,
2147
- type: "search",
2148
- value,
2149
- onChange: (event) => onChange(event.target.value),
2150
- className: cn(
2151
- "h-11 w-full rounded-full border border-input bg-background text-[15px] text-foreground placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
2152
- // Chromium/Safari render their own native clear (×) control on
2153
- // type="search" inputs -- left alone, it stacks on top of our own
2154
- // custom clear button below instead of replacing it.
2155
- "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
2156
- showClear ? "pr-11" : "pr-4",
2157
- "pl-11"
2158
- ),
2159
- ...props
2160
- }
2161
- ),
2162
- showClear && /* @__PURE__ */ jsx34(
2163
- "button",
2164
- {
2165
- type: "button",
2166
- onClick: () => onClear ? onClear() : onChange(""),
2167
- "aria-label": clearLabel,
2168
- className: "absolute top-1/2 right-2 flex h-7 w-7 -translate-y-1/2 items-center justify-center rounded-full text-muted-foreground hover:bg-accent hover:text-foreground",
2169
- children: /* @__PURE__ */ jsx34(X5, { className: "h-4 w-4", "aria-hidden": "true" })
2170
- }
2171
- )
2336
+ return /* @__PURE__ */ jsxs20("div", { className, children: [
2337
+ /* @__PURE__ */ jsxs20("div", { className: "relative", children: [
2338
+ /* @__PURE__ */ jsx37("span", { className: "pointer-events-none absolute top-1/2 left-4 -translate-y-1/2 text-muted-foreground", children: busy ? /* @__PURE__ */ jsx37(LoadingSpinner, { size: "sm" }) : hasError ? /* @__PURE__ */ jsx37(ExclamationTriangleIcon3, { className: "h-4 w-4 text-destructive", "aria-hidden": "true" }) : /* @__PURE__ */ jsx37(MagnifyingGlassIcon, { className: "h-4 w-4", "aria-hidden": "true" }) }),
2339
+ /* @__PURE__ */ jsx37(
2340
+ "input",
2341
+ {
2342
+ ref: inputRef,
2343
+ type: "search",
2344
+ "aria-invalid": hasError || void 0,
2345
+ value,
2346
+ onChange: (event) => onChange(event.target.value),
2347
+ className: cn(
2348
+ "h-11 w-full rounded-full border bg-background text-[15px] text-foreground placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
2349
+ // Chromium/Safari render their own native clear (×) control on
2350
+ // type="search" inputs -- left alone, it stacks on top of our own
2351
+ // custom clear button below instead of replacing it.
2352
+ "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
2353
+ hasError ? "border-destructive" : "border-input",
2354
+ showClear ? "pr-11" : "pr-4",
2355
+ "pl-11"
2356
+ ),
2357
+ ...props
2358
+ }
2359
+ ),
2360
+ showClear && /* @__PURE__ */ jsx37(
2361
+ "button",
2362
+ {
2363
+ type: "button",
2364
+ onClick: () => onClear ? onClear() : onChange(""),
2365
+ "aria-label": clearLabel,
2366
+ className: "absolute top-1/2 right-2 flex h-7 w-7 -translate-y-1/2 items-center justify-center rounded-full text-muted-foreground hover:bg-accent hover:text-foreground",
2367
+ children: /* @__PURE__ */ jsx37(XMarkIcon5, { className: "h-4 w-4", "aria-hidden": "true" })
2368
+ }
2369
+ )
2370
+ ] }),
2371
+ hasError && /* @__PURE__ */ jsx37(InlineError, { error, onRetry, className: "mt-1 ml-4" })
2172
2372
  ] });
2173
2373
  }
2174
2374
 
2175
2375
  // src/patterns/kpi-card/KpiCard.tsx
2176
2376
  import { memo } from "react";
2177
- import { Fragment as Fragment3, jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
2377
+ import { ExclamationTriangleIcon as ExclamationTriangleIcon4 } from "@heroicons/react/24/outline";
2378
+ import { Fragment as Fragment4, jsx as jsx38, jsxs as jsxs21 } from "react/jsx-runtime";
2178
2379
  var DONUT_COLORS = [
2179
2380
  "var(--chart-1, #3b82f6)",
2180
2381
  "var(--chart-2, #22c55e)",
@@ -2195,13 +2396,13 @@ function DonutChart({
2195
2396
  const radius = (size - thickness) / 2;
2196
2397
  const circumference = 2 * Math.PI * radius;
2197
2398
  let offset = 0;
2198
- return /* @__PURE__ */ jsxs18("div", { className: "relative inline-flex shrink-0 items-center justify-center", style: { width: size, height: size }, children: [
2199
- /* @__PURE__ */ jsxs18("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [
2200
- /* @__PURE__ */ jsx35("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: "currentColor", className: "text-muted/40", strokeWidth: thickness }),
2399
+ return /* @__PURE__ */ jsxs21("div", { className: "relative inline-flex shrink-0 items-center justify-center", style: { width: size, height: size }, children: [
2400
+ /* @__PURE__ */ jsxs21("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [
2401
+ /* @__PURE__ */ jsx38("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: "currentColor", className: "text-muted/40", strokeWidth: thickness }),
2201
2402
  data.map((segment, i) => {
2202
2403
  const fraction = segment.value / total;
2203
2404
  const dash = fraction * circumference;
2204
- const el = /* @__PURE__ */ jsx35(
2405
+ const el = /* @__PURE__ */ jsx38(
2205
2406
  "circle",
2206
2407
  {
2207
2408
  cx: size / 2,
@@ -2220,9 +2421,9 @@ function DonutChart({
2220
2421
  return el;
2221
2422
  })
2222
2423
  ] }),
2223
- (centerValue || centerLabel) && /* @__PURE__ */ jsxs18("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [
2224
- centerValue && /* @__PURE__ */ jsx35("span", { className: "text-base font-black tracking-tight text-foreground tabular-nums", children: centerValue }),
2225
- centerLabel && /* @__PURE__ */ jsx35("span", { className: "text-[9px] font-medium text-muted-foreground uppercase", children: centerLabel })
2424
+ (centerValue || centerLabel) && /* @__PURE__ */ jsxs21("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [
2425
+ centerValue && /* @__PURE__ */ jsx38("span", { className: "text-base font-black tracking-tight text-foreground tabular-nums", children: centerValue }),
2426
+ centerLabel && /* @__PURE__ */ jsx38("span", { className: "text-[9px] font-medium text-muted-foreground uppercase", children: centerLabel })
2226
2427
  ] })
2227
2428
  ] });
2228
2429
  }
@@ -2234,7 +2435,7 @@ function Sparkline({ data, color }) {
2234
2435
  const W = 72;
2235
2436
  const H = 28;
2236
2437
  const pts = data.map((v, i) => `${i / (data.length - 1) * W},${H - (v - min) / range * (H - 2) - 1}`).join(" ");
2237
- return /* @__PURE__ */ jsx35("svg", { width: W, height: H, viewBox: `0 0 ${W} ${H}`, className: "overflow-visible opacity-70", children: /* @__PURE__ */ jsx35("polyline", { points: pts, fill: "none", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
2438
+ return /* @__PURE__ */ jsx38("svg", { width: W, height: H, viewBox: `0 0 ${W} ${H}`, className: "overflow-visible opacity-70", children: /* @__PURE__ */ jsx38("polyline", { points: pts, fill: "none", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
2238
2439
  }
2239
2440
  function AreaSparkline({ data, color }) {
2240
2441
  if (data.length < 2) return null;
@@ -2248,14 +2449,14 @@ function AreaSparkline({ data, color }) {
2248
2449
  const ys = data.map((v) => H - (v - min) / range * (H - 2 * P) - P);
2249
2450
  const linePts = xs.map((x, i) => `${x},${ys[i]}`).join(" ");
2250
2451
  const areaPath = `M${xs[0]},${H} ` + xs.map((x, i) => `L${x},${ys[i]}`).join(" ") + ` L${xs[xs.length - 1]},${H} Z`;
2251
- return /* @__PURE__ */ jsxs18("svg", { width: W, height: H, viewBox: `0 0 ${W} ${H}`, className: "overflow-visible", preserveAspectRatio: "none", children: [
2252
- /* @__PURE__ */ jsx35("defs", { children: /* @__PURE__ */ jsxs18("linearGradient", { id: "kpi-card-spark-fill", x1: "0", y1: "0", x2: "0", y2: "1", children: [
2253
- /* @__PURE__ */ jsx35("stop", { offset: "0%", stopColor: color, stopOpacity: "0.22" }),
2254
- /* @__PURE__ */ jsx35("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
2452
+ return /* @__PURE__ */ jsxs21("svg", { width: W, height: H, viewBox: `0 0 ${W} ${H}`, className: "overflow-visible", preserveAspectRatio: "none", children: [
2453
+ /* @__PURE__ */ jsx38("defs", { children: /* @__PURE__ */ jsxs21("linearGradient", { id: "kpi-card-spark-fill", x1: "0", y1: "0", x2: "0", y2: "1", children: [
2454
+ /* @__PURE__ */ jsx38("stop", { offset: "0%", stopColor: color, stopOpacity: "0.22" }),
2455
+ /* @__PURE__ */ jsx38("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
2255
2456
  ] }) }),
2256
- /* @__PURE__ */ jsx35("path", { d: areaPath, fill: "url(#kpi-card-spark-fill)" }),
2257
- /* @__PURE__ */ jsx35("polyline", { points: linePts, fill: "none", stroke: color, strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }),
2258
- /* @__PURE__ */ jsx35("circle", { cx: xs[xs.length - 1], cy: ys[ys.length - 1], r: "2.5", fill: color })
2457
+ /* @__PURE__ */ jsx38("path", { d: areaPath, fill: "url(#kpi-card-spark-fill)" }),
2458
+ /* @__PURE__ */ jsx38("polyline", { points: linePts, fill: "none", stroke: color, strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }),
2459
+ /* @__PURE__ */ jsx38("circle", { cx: xs[xs.length - 1], cy: ys[ys.length - 1], r: "2.5", fill: color })
2259
2460
  ] });
2260
2461
  }
2261
2462
  var rowBetween = "flex items-center justify-between";
@@ -2267,6 +2468,8 @@ var KpiCard = memo(function KpiCard2({
2267
2468
  badgeLabel,
2268
2469
  variant = "default",
2269
2470
  loading = false,
2471
+ error,
2472
+ onRetry,
2270
2473
  sub,
2271
2474
  subTone = "default",
2272
2475
  href,
@@ -2279,9 +2482,33 @@ var KpiCard = memo(function KpiCard2({
2279
2482
  background,
2280
2483
  testId
2281
2484
  }) {
2485
+ const errorInfo = loading ? void 0 : toErrorInfo(error);
2486
+ if (errorInfo) {
2487
+ const hero = variant === "hero";
2488
+ return /* @__PURE__ */ jsxs21(
2489
+ "div",
2490
+ {
2491
+ "data-testid": testId,
2492
+ role: "status",
2493
+ className: cn(
2494
+ "flex min-w-0 flex-col gap-1 rounded-2xl border border-destructive/40 bg-card p-3",
2495
+ hero && "col-span-2 flex-1 lg:col-span-1 lg:max-w-[340px] lg:min-w-[260px]"
2496
+ ),
2497
+ children: [
2498
+ /* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.14em] text-muted-foreground uppercase", children: label }),
2499
+ /* @__PURE__ */ jsxs21("p", { className: "flex items-center gap-1.5 text-xl font-bold text-muted-foreground", children: [
2500
+ "\u2014",
2501
+ /* @__PURE__ */ jsx38(ExclamationTriangleIcon4, { className: "h-4 w-4 text-destructive", "aria-hidden": "true" })
2502
+ ] }),
2503
+ /* @__PURE__ */ jsx38("p", { className: "truncate text-xs text-red-700 dark:text-red-300", children: errorInfo.message ?? errorInfo.title ?? "Failed to load" }),
2504
+ onRetry ? /* @__PURE__ */ jsx38("button", { type: "button", onClick: onRetry, className: "self-start text-xs text-red-700 underline underline-offset-2 dark:text-red-300", children: "Retry" }) : null
2505
+ ]
2506
+ }
2507
+ );
2508
+ }
2282
2509
  const bgStyle = background ? { background } : void 0;
2283
2510
  if (variant === "hero") {
2284
- return /* @__PURE__ */ jsxs18(
2511
+ return /* @__PURE__ */ jsxs21(
2285
2512
  "div",
2286
2513
  {
2287
2514
  "data-testid": testId,
@@ -2291,13 +2518,13 @@ var KpiCard = memo(function KpiCard2({
2291
2518
  boxShadow: `0 2px 10px color-mix(in oklch, ${background ?? "var(--color-primary)"} 18%, transparent)`
2292
2519
  },
2293
2520
  children: [
2294
- /* @__PURE__ */ jsxs18("div", { className: "relative flex items-start justify-between", children: [
2295
- /* @__PURE__ */ jsx35("p", { className: "text-[11px] font-bold tracking-[0.14em] text-white/70 uppercase", children: label }),
2296
- Icon2 && /* @__PURE__ */ jsx35("div", { className: "flex h-6 w-6 items-center justify-center rounded-lg bg-white/15 ring-1 ring-white/20", children: /* @__PURE__ */ jsx35(Icon2, { className: "h-3 w-3 text-white/90", "aria-hidden": "true" }) })
2521
+ /* @__PURE__ */ jsxs21("div", { className: "relative flex items-start justify-between", children: [
2522
+ /* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.14em] text-white/70 uppercase", children: label }),
2523
+ Icon2 && /* @__PURE__ */ jsx38("div", { className: "flex h-6 w-6 items-center justify-center rounded-lg bg-white/15 ring-1 ring-white/20", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-3 w-3 text-white/90", "aria-hidden": "true" }) })
2297
2524
  ] }),
2298
- /* @__PURE__ */ jsx35("div", { className: "relative", children: loading ? /* @__PURE__ */ jsx35("div", { className: "h-6 w-28 animate-pulse rounded-lg bg-white/15" }) : /* @__PURE__ */ jsx35("p", { className: "text-2xl leading-none font-black tracking-tight text-white tabular-nums md:text-[22px]", children: value ?? "\u2014" }) }),
2299
- (badge || badgeLabel) && !loading && /* @__PURE__ */ jsxs18("div", { className: "relative flex items-center gap-2", children: [
2300
- badge && /* @__PURE__ */ jsx35(
2525
+ /* @__PURE__ */ jsx38("div", { className: "relative", children: loading ? /* @__PURE__ */ jsx38("div", { className: "h-6 w-28 animate-pulse rounded-lg bg-white/15" }) : /* @__PURE__ */ jsx38("p", { className: "text-2xl leading-none font-black tracking-tight text-white tabular-nums md:text-[22px]", children: value ?? "\u2014" }) }),
2526
+ (badge || badgeLabel) && !loading && /* @__PURE__ */ jsxs21("div", { className: "relative flex items-center gap-2", children: [
2527
+ badge && /* @__PURE__ */ jsx38(
2301
2528
  "span",
2302
2529
  {
2303
2530
  className: cn(
@@ -2307,28 +2534,28 @@ var KpiCard = memo(function KpiCard2({
2307
2534
  children: badge.text
2308
2535
  }
2309
2536
  ),
2310
- badgeLabel && /* @__PURE__ */ jsx35("span", { className: "text-[11px] text-white/70", children: badgeLabel })
2537
+ badgeLabel && /* @__PURE__ */ jsx38("span", { className: "text-[11px] text-white/70", children: badgeLabel })
2311
2538
  ] }),
2312
- sub && !loading && /* @__PURE__ */ jsx35("p", { className: "relative -mt-1 text-[11px] font-medium text-white/75 tabular-nums", children: sub }),
2313
- progress != null && !loading && /* @__PURE__ */ jsxs18("div", { className: "relative flex items-center gap-1.5", children: [
2314
- /* @__PURE__ */ jsx35("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-white/20", children: /* @__PURE__ */ jsx35("div", { className: "h-1 rounded-full bg-white/85", style: { width: `${Math.min(100, Math.max(0, progress))}%` } }) }),
2315
- progressLabel && /* @__PURE__ */ jsx35("span", { className: "shrink-0 text-[11px] font-semibold text-white/80 tabular-nums", children: progressLabel })
2539
+ sub && !loading && /* @__PURE__ */ jsx38("p", { className: "relative -mt-1 text-[11px] font-medium text-white/75 tabular-nums", children: sub }),
2540
+ progress != null && !loading && /* @__PURE__ */ jsxs21("div", { className: "relative flex items-center gap-1.5", children: [
2541
+ /* @__PURE__ */ jsx38("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-white/20", children: /* @__PURE__ */ jsx38("div", { className: "h-1 rounded-full bg-white/85", style: { width: `${Math.min(100, Math.max(0, progress))}%` } }) }),
2542
+ progressLabel && /* @__PURE__ */ jsx38("span", { className: "shrink-0 text-[11px] font-semibold text-white/80 tabular-nums", children: progressLabel })
2316
2543
  ] }),
2317
- sparkline && sparkline.length > 1 && !loading && /* @__PURE__ */ jsx35("div", { className: "relative -mx-4 mt-auto -mb-4 md:-mx-3 md:-mb-3", children: /* @__PURE__ */ jsx35(AreaSparkline, { data: sparkline, color: "#ffffff" }) })
2544
+ sparkline && sparkline.length > 1 && !loading && /* @__PURE__ */ jsx38("div", { className: "relative -mx-4 mt-auto -mb-4 md:-mx-3 md:-mb-3", children: /* @__PURE__ */ jsx38(AreaSparkline, { data: sparkline, color: "#ffffff" }) })
2318
2545
  ]
2319
2546
  }
2320
2547
  );
2321
2548
  }
2322
2549
  if (variant === "mini") {
2323
- const iconSlot = Icon2 ? href ? /* @__PURE__ */ jsx35(
2550
+ const iconSlot = Icon2 ? href ? /* @__PURE__ */ jsx38(
2324
2551
  "a",
2325
2552
  {
2326
2553
  href,
2327
2554
  className: "tap-target flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary transition-[background-color,scale] hover:bg-primary/20 active:scale-90 motion-reduce:transition-none md:h-6 md:w-6",
2328
- children: /* @__PURE__ */ jsx35(Icon2, { className: "h-4 w-4 md:h-3.5 md:w-3.5", "aria-hidden": "true" })
2555
+ children: /* @__PURE__ */ jsx38(Icon2, { className: "h-4 w-4 md:h-3.5 md:w-3.5", "aria-hidden": "true" })
2329
2556
  }
2330
- ) : /* @__PURE__ */ jsx35("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary md:h-6 md:w-6", children: /* @__PURE__ */ jsx35(Icon2, { className: "h-4 w-4 md:h-3.5 md:w-3.5", "aria-hidden": "true" }) }) : null;
2331
- return /* @__PURE__ */ jsxs18(
2557
+ ) : /* @__PURE__ */ jsx38("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary md:h-6 md:w-6", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-4 w-4 md:h-3.5 md:w-3.5", "aria-hidden": "true" }) }) : null;
2558
+ return /* @__PURE__ */ jsxs21(
2332
2559
  "div",
2333
2560
  {
2334
2561
  "data-testid": testId,
@@ -2338,13 +2565,13 @@ var KpiCard = memo(function KpiCard2({
2338
2565
  href && "hover:border-primary/20 hover:shadow-md"
2339
2566
  ),
2340
2567
  children: [
2341
- /* @__PURE__ */ jsxs18("div", { className: rowBetween, children: [
2342
- /* @__PURE__ */ jsx35("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
2568
+ /* @__PURE__ */ jsxs21("div", { className: rowBetween, children: [
2569
+ /* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
2343
2570
  iconSlot
2344
2571
  ] }),
2345
- /* @__PURE__ */ jsx35("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: loading ? /* @__PURE__ */ jsx35(Skeleton, { className: "h-6 w-16" }) : /* @__PURE__ */ jsxs18(Fragment3, { children: [
2346
- /* @__PURE__ */ jsx35("p", { className: "min-w-0 animate-in truncate text-[20px] leading-none font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none md:text-[16px]", children: value ?? "\u2014" }),
2347
- badge && /* @__PURE__ */ jsx35(
2572
+ /* @__PURE__ */ jsx38("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: loading ? /* @__PURE__ */ jsx38(Skeleton, { className: "h-6 w-16" }) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
2573
+ /* @__PURE__ */ jsx38("p", { className: "min-w-0 animate-in truncate text-[20px] leading-none font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none md:text-[16px]", children: value ?? "\u2014" }),
2574
+ badge && /* @__PURE__ */ jsx38(
2348
2575
  "span",
2349
2576
  {
2350
2577
  className: cn(
@@ -2355,8 +2582,8 @@ var KpiCard = memo(function KpiCard2({
2355
2582
  }
2356
2583
  )
2357
2584
  ] }) }),
2358
- (sub || sparkline) && !loading && /* @__PURE__ */ jsxs18("div", { className: "flex items-end justify-between gap-2", children: [
2359
- sub && /* @__PURE__ */ jsx35(
2585
+ (sub || sparkline) && !loading && /* @__PURE__ */ jsxs21("div", { className: "flex items-end justify-between gap-2", children: [
2586
+ sub && /* @__PURE__ */ jsx38(
2360
2587
  "p",
2361
2588
  {
2362
2589
  className: cn(
@@ -2366,7 +2593,7 @@ var KpiCard = memo(function KpiCard2({
2366
2593
  children: sub
2367
2594
  }
2368
2595
  ),
2369
- sparkline && /* @__PURE__ */ jsx35(Sparkline, { data: sparkline, color: sparklineColor })
2596
+ sparkline && /* @__PURE__ */ jsx38(Sparkline, { data: sparkline, color: sparklineColor })
2370
2597
  ] })
2371
2598
  ]
2372
2599
  }
@@ -2374,22 +2601,22 @@ var KpiCard = memo(function KpiCard2({
2374
2601
  }
2375
2602
  if (variant === "donut") {
2376
2603
  const total = segments?.reduce((sum, s) => sum + s.value, 0) ?? 0;
2377
- return /* @__PURE__ */ jsxs18("div", { "data-testid": testId, style: bgStyle, className: "rounded-xl border border-border bg-card p-5", children: [
2378
- /* @__PURE__ */ jsxs18("div", { className: rowBetween, children: [
2379
- /* @__PURE__ */ jsx35("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
2380
- Icon2 && /* @__PURE__ */ jsx35("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/8 text-primary", children: /* @__PURE__ */ jsx35(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })
2604
+ return /* @__PURE__ */ jsxs21("div", { "data-testid": testId, style: bgStyle, className: "rounded-xl border border-border bg-card p-5", children: [
2605
+ /* @__PURE__ */ jsxs21("div", { className: rowBetween, children: [
2606
+ /* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
2607
+ Icon2 && /* @__PURE__ */ jsx38("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/8 text-primary", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })
2381
2608
  ] }),
2382
- loading ? /* @__PURE__ */ jsxs18("div", { className: "mt-3 flex items-center gap-4", children: [
2383
- /* @__PURE__ */ jsx35(Skeleton, { className: "h-24 w-24 shrink-0 rounded-full" }),
2384
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-1 flex-col gap-2", children: [
2385
- /* @__PURE__ */ jsx35(Skeleton, { className: "h-3 w-full" }),
2386
- /* @__PURE__ */ jsx35(Skeleton, { className: "h-3 w-3/4" }),
2387
- /* @__PURE__ */ jsx35(Skeleton, { className: "h-3 w-1/2" })
2609
+ loading ? /* @__PURE__ */ jsxs21("div", { className: "mt-3 flex items-center gap-4", children: [
2610
+ /* @__PURE__ */ jsx38(Skeleton, { className: "h-24 w-24 shrink-0 rounded-full" }),
2611
+ /* @__PURE__ */ jsxs21("div", { className: "flex flex-1 flex-col gap-2", children: [
2612
+ /* @__PURE__ */ jsx38(Skeleton, { className: "h-3 w-full" }),
2613
+ /* @__PURE__ */ jsx38(Skeleton, { className: "h-3 w-3/4" }),
2614
+ /* @__PURE__ */ jsx38(Skeleton, { className: "h-3 w-1/2" })
2388
2615
  ] })
2389
- ] }) : segments && segments.length > 0 ? /* @__PURE__ */ jsxs18("div", { className: "mt-3 flex items-center gap-4", children: [
2390
- /* @__PURE__ */ jsx35(DonutChart, { data: segments, centerValue: centerValue ?? String(total) }),
2391
- /* @__PURE__ */ jsx35("ul", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: segments.map((segment, i) => /* @__PURE__ */ jsxs18("li", { className: "flex items-center gap-2 text-[12px]", children: [
2392
- /* @__PURE__ */ jsx35(
2616
+ ] }) : segments && segments.length > 0 ? /* @__PURE__ */ jsxs21("div", { className: "mt-3 flex items-center gap-4", children: [
2617
+ /* @__PURE__ */ jsx38(DonutChart, { data: segments, centerValue: centerValue ?? String(total) }),
2618
+ /* @__PURE__ */ jsx38("ul", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: segments.map((segment, i) => /* @__PURE__ */ jsxs21("li", { className: "flex items-center gap-2 text-[12px]", children: [
2619
+ /* @__PURE__ */ jsx38(
2393
2620
  "span",
2394
2621
  {
2395
2622
  className: "h-2 w-2 shrink-0 rounded-full",
@@ -2397,11 +2624,11 @@ var KpiCard = memo(function KpiCard2({
2397
2624
  "aria-hidden": "true"
2398
2625
  }
2399
2626
  ),
2400
- /* @__PURE__ */ jsx35("span", { className: "min-w-0 flex-1 truncate text-muted-foreground", children: segment.label }),
2401
- /* @__PURE__ */ jsx35("span", { className: "shrink-0 font-semibold text-foreground tabular-nums", children: total > 0 ? `${Math.round(segment.value / total * 100)}%` : segment.value })
2627
+ /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate text-muted-foreground", children: segment.label }),
2628
+ /* @__PURE__ */ jsx38("span", { className: "shrink-0 font-semibold text-foreground tabular-nums", children: total > 0 ? `${Math.round(segment.value / total * 100)}%` : segment.value })
2402
2629
  ] }, segment.label)) })
2403
- ] }) : /* @__PURE__ */ jsx35("span", { className: "mt-3 block text-2xl font-black text-muted-foreground/40", children: "\u2014" }),
2404
- sub && !loading && /* @__PURE__ */ jsx35("p", { className: "mt-2.5 text-[11px] text-muted-foreground tabular-nums", children: sub })
2630
+ ] }) : /* @__PURE__ */ jsx38("span", { className: "mt-3 block text-2xl font-black text-muted-foreground/40", children: "\u2014" }),
2631
+ sub && !loading && /* @__PURE__ */ jsx38("p", { className: "mt-2.5 text-[11px] text-muted-foreground tabular-nums", children: sub })
2405
2632
  ] });
2406
2633
  }
2407
2634
  const strValue = value != null ? String(value) : null;
@@ -2411,28 +2638,28 @@ var KpiCard = memo(function KpiCard2({
2411
2638
  const prefix = isSuffix ? null : parts?.[0];
2412
2639
  const number = isSuffix ? parts[0] : parts?.[1] ?? parts?.[0];
2413
2640
  const suffix = isSuffix ? parts[1] : null;
2414
- return /* @__PURE__ */ jsxs18("div", { "data-testid": testId, style: bgStyle, className: "rounded-xl border border-border bg-card p-5", children: [
2415
- /* @__PURE__ */ jsxs18("div", { className: rowBetween, children: [
2416
- /* @__PURE__ */ jsx35("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
2417
- Icon2 && /* @__PURE__ */ jsx35("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/8 text-primary", children: /* @__PURE__ */ jsx35(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })
2641
+ return /* @__PURE__ */ jsxs21("div", { "data-testid": testId, style: bgStyle, className: "rounded-xl border border-border bg-card p-5", children: [
2642
+ /* @__PURE__ */ jsxs21("div", { className: rowBetween, children: [
2643
+ /* @__PURE__ */ jsx38("p", { className: "text-[11px] font-bold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
2644
+ Icon2 && /* @__PURE__ */ jsx38("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary/8 text-primary", children: /* @__PURE__ */ jsx38(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) })
2418
2645
  ] }),
2419
- /* @__PURE__ */ jsxs18("div", { className: "mt-3", children: [
2420
- loading ? /* @__PURE__ */ jsx35(Skeleton, { className: "h-7 w-20" }) : value == null ? /* @__PURE__ */ jsx35("span", { className: "text-2xl font-black text-muted-foreground/40", children: "\u2014" }) : plain ? /* @__PURE__ */ jsx35("span", { className: "animate-in text-2xl font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none", children: strValue }) : /* @__PURE__ */ jsxs18("span", { className: "animate-in font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none", children: [
2421
- prefix && /* @__PURE__ */ jsxs18("span", { className: "text-sm text-muted-foreground", children: [
2646
+ /* @__PURE__ */ jsxs21("div", { className: "mt-3", children: [
2647
+ loading ? /* @__PURE__ */ jsx38(Skeleton, { className: "h-7 w-20" }) : value == null ? /* @__PURE__ */ jsx38("span", { className: "text-2xl font-black text-muted-foreground/40", children: "\u2014" }) : plain ? /* @__PURE__ */ jsx38("span", { className: "animate-in text-2xl font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none", children: strValue }) : /* @__PURE__ */ jsxs21("span", { className: "animate-in font-black tracking-tight text-foreground duration-200 fade-in-0 tabular-nums motion-reduce:animate-none", children: [
2648
+ prefix && /* @__PURE__ */ jsxs21("span", { className: "text-sm text-muted-foreground", children: [
2422
2649
  prefix,
2423
2650
  " "
2424
2651
  ] }),
2425
- /* @__PURE__ */ jsx35("span", { className: "text-2xl", children: number }),
2426
- suffix && /* @__PURE__ */ jsxs18("span", { className: "text-sm text-muted-foreground", children: [
2652
+ /* @__PURE__ */ jsx38("span", { className: "text-2xl", children: number }),
2653
+ suffix && /* @__PURE__ */ jsxs21("span", { className: "text-sm text-muted-foreground", children: [
2427
2654
  " ",
2428
2655
  suffix
2429
2656
  ] })
2430
2657
  ] }),
2431
- sub && !loading && /* @__PURE__ */ jsx35("p", { className: "mt-0.5 text-[11px] text-muted-foreground tabular-nums", children: sub })
2658
+ sub && !loading && /* @__PURE__ */ jsx38("p", { className: "mt-0.5 text-[11px] text-muted-foreground tabular-nums", children: sub })
2432
2659
  ] }),
2433
- (badge || badgeLabel || sparkline) && !loading && /* @__PURE__ */ jsxs18("div", { className: "mt-2.5 flex items-end justify-between gap-2", children: [
2434
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-wrap items-center gap-2", children: [
2435
- badge && /* @__PURE__ */ jsx35(
2660
+ (badge || badgeLabel || sparkline) && !loading && /* @__PURE__ */ jsxs21("div", { className: "mt-2.5 flex items-end justify-between gap-2", children: [
2661
+ /* @__PURE__ */ jsxs21("div", { className: "flex flex-wrap items-center gap-2", children: [
2662
+ badge && /* @__PURE__ */ jsx38(
2436
2663
  "span",
2437
2664
  {
2438
2665
  className: cn(
@@ -2442,20 +2669,23 @@ var KpiCard = memo(function KpiCard2({
2442
2669
  children: badge.text
2443
2670
  }
2444
2671
  ),
2445
- badgeLabel && /* @__PURE__ */ jsx35("span", { className: "text-[11px] text-muted-foreground", children: badgeLabel })
2672
+ badgeLabel && /* @__PURE__ */ jsx38("span", { className: "text-[11px] text-muted-foreground", children: badgeLabel })
2446
2673
  ] }),
2447
- sparkline && /* @__PURE__ */ jsx35(Sparkline, { data: sparkline, color: sparklineColor })
2674
+ sparkline && /* @__PURE__ */ jsx38(Sparkline, { data: sparkline, color: sparklineColor })
2448
2675
  ] })
2449
2676
  ] });
2450
2677
  });
2451
2678
 
2452
2679
  // src/patterns/search-panel/SearchPanel.tsx
2453
- import { Search as Search2 } from "lucide-react";
2454
- import { jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
2680
+ import { ExclamationTriangleIcon as ExclamationTriangleIcon5, MagnifyingGlassIcon as MagnifyingGlassIcon2 } from "@heroicons/react/24/outline";
2681
+ import { jsx as jsx39, jsxs as jsxs22 } from "react/jsx-runtime";
2455
2682
  function SearchPanel({
2456
2683
  value,
2457
2684
  onChange,
2685
+ loading,
2458
2686
  isLoading,
2687
+ error,
2688
+ onRetry,
2459
2689
  trailingSlot,
2460
2690
  shortcutHint,
2461
2691
  modes,
@@ -2466,7 +2696,9 @@ function SearchPanel({
2466
2696
  className,
2467
2697
  ...props
2468
2698
  }) {
2469
- return /* @__PURE__ */ jsxs19(
2699
+ const busy = loading ?? isLoading;
2700
+ const hasError = toErrorInfo(error) !== void 0;
2701
+ return /* @__PURE__ */ jsxs22(
2470
2702
  "div",
2471
2703
  {
2472
2704
  className: cn(
@@ -2475,9 +2707,9 @@ function SearchPanel({
2475
2707
  className
2476
2708
  ),
2477
2709
  children: [
2478
- /* @__PURE__ */ jsxs19("div", { className: "flex h-14 items-center gap-3 px-4", children: [
2479
- isLoading ? /* @__PURE__ */ jsx36(LoadingSpinner, { size: "sm" }) : /* @__PURE__ */ jsx36(Search2, { className: "h-5 w-5 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
2480
- /* @__PURE__ */ jsx36(
2710
+ /* @__PURE__ */ jsxs22("div", { className: "flex h-14 items-center gap-3 px-4", children: [
2711
+ busy ? /* @__PURE__ */ jsx39(LoadingSpinner, { size: "sm" }) : hasError ? /* @__PURE__ */ jsx39(ExclamationTriangleIcon5, { className: "h-5 w-5 shrink-0 text-destructive", "aria-hidden": "true" }) : /* @__PURE__ */ jsx39(MagnifyingGlassIcon2, { className: "h-5 w-5 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
2712
+ /* @__PURE__ */ jsx39(
2481
2713
  "input",
2482
2714
  {
2483
2715
  ref: inputRef,
@@ -2489,7 +2721,7 @@ function SearchPanel({
2489
2721
  }
2490
2722
  ),
2491
2723
  trailingSlot,
2492
- shortcutHint && /* @__PURE__ */ jsx36(
2724
+ shortcutHint && /* @__PURE__ */ jsx39(
2493
2725
  "kbd",
2494
2726
  {
2495
2727
  "aria-hidden": "true",
@@ -2498,7 +2730,8 @@ function SearchPanel({
2498
2730
  }
2499
2731
  )
2500
2732
  ] }),
2501
- modes && modes.length > 0 && /* @__PURE__ */ jsx36("div", { className: "flex items-center gap-2 px-4 pb-3", children: modes.map(({ key, label, icon: Icon2 }) => /* @__PURE__ */ jsxs19(
2733
+ hasError && /* @__PURE__ */ jsx39("div", { className: "px-4 pb-3", children: /* @__PURE__ */ jsx39(InlineError, { error, onRetry }) }),
2734
+ modes && modes.length > 0 && /* @__PURE__ */ jsx39("div", { className: "flex items-center gap-2 px-4 pb-3", children: modes.map(({ key, label, icon: Icon2 }) => /* @__PURE__ */ jsxs22(
2502
2735
  "button",
2503
2736
  {
2504
2737
  type: "button",
@@ -2508,7 +2741,7 @@ function SearchPanel({
2508
2741
  activeMode === key ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
2509
2742
  ),
2510
2743
  children: [
2511
- Icon2 && /* @__PURE__ */ jsx36(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
2744
+ Icon2 && /* @__PURE__ */ jsx39(Icon2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
2512
2745
  label
2513
2746
  ]
2514
2747
  },
@@ -2520,10 +2753,10 @@ function SearchPanel({
2520
2753
  }
2521
2754
 
2522
2755
  // src/patterns/search-panel/SearchTrigger.tsx
2523
- import { Search as Search3 } from "lucide-react";
2524
- import { jsx as jsx37 } from "react/jsx-runtime";
2756
+ import { MagnifyingGlassIcon as MagnifyingGlassIcon3 } from "@heroicons/react/24/outline";
2757
+ import { jsx as jsx40 } from "react/jsx-runtime";
2525
2758
  function SearchTrigger({ label = "Search", ...props }) {
2526
- return /* @__PURE__ */ jsx37(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": label, ...props, children: /* @__PURE__ */ jsx37(Search3, { className: "h-[18px] w-[18px]", "aria-hidden": "true" }) });
2759
+ return /* @__PURE__ */ jsx40(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": label, ...props, children: /* @__PURE__ */ jsx40(MagnifyingGlassIcon3, { className: "h-[18px] w-[18px]", "aria-hidden": "true" }) });
2527
2760
  }
2528
2761
 
2529
2762
  // src/patterns/sidebar/context.ts
@@ -2535,7 +2768,7 @@ function useSidebarCollapsed() {
2535
2768
  }
2536
2769
 
2537
2770
  // src/patterns/sidebar/NavItem.tsx
2538
- import { jsx as jsx38, jsxs as jsxs20 } from "react/jsx-runtime";
2771
+ import { jsx as jsx41, jsxs as jsxs23 } from "react/jsx-runtime";
2539
2772
  function NavItem({
2540
2773
  as,
2541
2774
  icon: Icon2,
@@ -2547,7 +2780,7 @@ function NavItem({
2547
2780
  }) {
2548
2781
  const collapsed = useSidebarCollapsed();
2549
2782
  const Comp = as ?? "a";
2550
- const row = /* @__PURE__ */ jsxs20(
2783
+ const row = /* @__PURE__ */ jsxs23(
2551
2784
  Comp,
2552
2785
  {
2553
2786
  className: cn(
@@ -2559,7 +2792,7 @@ function NavItem({
2559
2792
  ),
2560
2793
  ...rest,
2561
2794
  children: [
2562
- Icon2 && /* @__PURE__ */ jsx38(
2795
+ Icon2 && /* @__PURE__ */ jsx41(
2563
2796
  Icon2,
2564
2797
  {
2565
2798
  className: cn("h-[18px] w-[18px] shrink-0", active ? "text-nav-primary" : "text-muted-foreground"),
@@ -2567,7 +2800,7 @@ function NavItem({
2567
2800
  "aria-hidden": true
2568
2801
  }
2569
2802
  ),
2570
- /* @__PURE__ */ jsx38(
2803
+ /* @__PURE__ */ jsx41(
2571
2804
  "span",
2572
2805
  {
2573
2806
  className: cn(
@@ -2582,9 +2815,9 @@ function NavItem({
2582
2815
  }
2583
2816
  );
2584
2817
  if (!collapsed) return row;
2585
- return /* @__PURE__ */ jsxs20(Tooltip, { children: [
2586
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: row }),
2587
- /* @__PURE__ */ jsxs20(TooltipContent, { side: "right", className: "flex items-center gap-1.5", children: [
2818
+ return /* @__PURE__ */ jsxs23(Tooltip, { children: [
2819
+ /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: row }),
2820
+ /* @__PURE__ */ jsxs23(TooltipContent, { side: "right", className: "flex items-center gap-1.5", children: [
2588
2821
  label,
2589
2822
  badge
2590
2823
  ] })
@@ -2592,9 +2825,9 @@ function NavItem({
2592
2825
  }
2593
2826
 
2594
2827
  // src/patterns/sidebar/NavGroup.tsx
2595
- import { ChevronDown as ChevronDown2 } from "lucide-react";
2596
- import { useState as useState10 } from "react";
2597
- import { jsx as jsx39, jsxs as jsxs21 } from "react/jsx-runtime";
2828
+ import { ChevronDownIcon as ChevronDownIcon2 } from "@heroicons/react/24/outline";
2829
+ import { useState as useState11 } from "react";
2830
+ import { jsx as jsx42, jsxs as jsxs24 } from "react/jsx-runtime";
2598
2831
  function NavGroup({
2599
2832
  label,
2600
2833
  defaultCollapsed = false,
@@ -2603,15 +2836,15 @@ function NavGroup({
2603
2836
  children,
2604
2837
  className
2605
2838
  }) {
2606
- const [internalCollapsed, setInternalCollapsed] = useState10(defaultCollapsed);
2839
+ const [internalCollapsed, setInternalCollapsed] = useState11(defaultCollapsed);
2607
2840
  const groupCollapsed = collapsed ?? internalCollapsed;
2608
2841
  const railCollapsed = useSidebarCollapsed();
2609
2842
  const setGroupCollapsed = (next) => {
2610
2843
  onCollapsedChange?.(next);
2611
2844
  if (collapsed === void 0) setInternalCollapsed(next);
2612
2845
  };
2613
- return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-col gap-0.5", className), children: [
2614
- label && (railCollapsed ? /* @__PURE__ */ jsx39("div", { className: "mx-2 my-1 h-px bg-border/50", "aria-hidden": true }) : /* @__PURE__ */ jsxs21(
2846
+ return /* @__PURE__ */ jsxs24("div", { className: cn("flex flex-col gap-0.5", className), children: [
2847
+ label && (railCollapsed ? /* @__PURE__ */ jsx42("div", { className: "mx-2 my-1 h-px bg-border/50", "aria-hidden": true }) : /* @__PURE__ */ jsxs24(
2615
2848
  "button",
2616
2849
  {
2617
2850
  type: "button",
@@ -2619,9 +2852,9 @@ function NavGroup({
2619
2852
  "aria-expanded": !groupCollapsed,
2620
2853
  className: "group flex w-full items-center justify-between px-2.5 py-0.5 text-[11px] font-medium text-muted-foreground/80 hover:text-foreground",
2621
2854
  children: [
2622
- /* @__PURE__ */ jsx39("span", { children: label }),
2623
- /* @__PURE__ */ jsx39(
2624
- ChevronDown2,
2855
+ /* @__PURE__ */ jsx42("span", { children: label }),
2856
+ /* @__PURE__ */ jsx42(
2857
+ ChevronDownIcon2,
2625
2858
  {
2626
2859
  className: cn(
2627
2860
  "h-4 w-4 opacity-40 transition-transform group-hover:opacity-100",
@@ -2633,19 +2866,19 @@ function NavGroup({
2633
2866
  ]
2634
2867
  }
2635
2868
  )),
2636
- !groupCollapsed && /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-0.5", children })
2869
+ !groupCollapsed && /* @__PURE__ */ jsx42("div", { className: "flex flex-col gap-0.5", children })
2637
2870
  ] });
2638
2871
  }
2639
2872
 
2640
2873
  // src/patterns/sidebar/Sidebar.tsx
2641
- import { PanelLeftClose, PanelLeftOpen } from "lucide-react";
2874
+ import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon } from "@heroicons/react/24/outline";
2642
2875
  import {
2643
2876
  useCallback as useCallback2,
2644
- useEffect as useEffect5,
2877
+ useEffect as useEffect6,
2645
2878
  useRef as useRef6,
2646
- useState as useState11
2879
+ useState as useState12
2647
2880
  } from "react";
2648
- import { Fragment as Fragment4, jsx as jsx40, jsxs as jsxs22 } from "react/jsx-runtime";
2881
+ import { Fragment as Fragment5, jsx as jsx43, jsxs as jsxs25 } from "react/jsx-runtime";
2649
2882
  function resolve(value, collapsed) {
2650
2883
  return typeof value === "function" ? value(collapsed) : value;
2651
2884
  }
@@ -2664,9 +2897,9 @@ function Sidebar({
2664
2897
  children,
2665
2898
  className
2666
2899
  }) {
2667
- const [internalWidth, setInternalWidth] = useState11(defaultWidth);
2900
+ const [internalWidth, setInternalWidth] = useState12(defaultWidth);
2668
2901
  const currentWidth = width ?? internalWidth;
2669
- const [isDragging, setIsDragging] = useState11(false);
2902
+ const [isDragging, setIsDragging] = useState12(false);
2670
2903
  const setWidth = useCallback2(
2671
2904
  (next) => {
2672
2905
  const clamped = Math.min(maxWidth, Math.max(minWidth, next));
@@ -2692,7 +2925,7 @@ function Sidebar({
2692
2925
  dragStartRef.current = null;
2693
2926
  setIsDragging(false);
2694
2927
  };
2695
- return /* @__PURE__ */ jsx40(SidebarContextProvider, { value: { collapsed }, children: /* @__PURE__ */ jsx40(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs22(
2928
+ return /* @__PURE__ */ jsx43(SidebarContextProvider, { value: { collapsed }, children: /* @__PURE__ */ jsx43(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs25(
2696
2929
  "aside",
2697
2930
  {
2698
2931
  style: { width: collapsed ? railWidth : currentWidth },
@@ -2702,13 +2935,13 @@ function Sidebar({
2702
2935
  className
2703
2936
  ),
2704
2937
  children: [
2705
- (header || onCollapsedChange) && /* @__PURE__ */ jsx40("div", { className: "flex h-16 items-center gap-2 border-b border-border px-3", children: collapsed && onCollapsedChange ? (
2938
+ (header || onCollapsedChange) && /* @__PURE__ */ jsx43("div", { className: "flex h-16 items-center gap-2 border-b border-border px-3", children: collapsed && onCollapsedChange ? (
2706
2939
  // Collapsed rail: the header slot (e.g. a compact logo mark) and the
2707
2940
  // expand toggle would otherwise compete for the narrow rail's width
2708
2941
  // and clip each other, so they're stacked instead — the header shows
2709
2942
  // by default and cross-fades to the toggle icon on hover, matching
2710
2943
  // the same affordance OneSales' own sidebar rail uses.
2711
- /* @__PURE__ */ jsxs22(
2944
+ /* @__PURE__ */ jsxs25(
2712
2945
  "button",
2713
2946
  {
2714
2947
  type: "button",
@@ -2716,9 +2949,9 @@ function Sidebar({
2716
2949
  "aria-label": "Expand sidebar",
2717
2950
  className: "group relative flex h-9 w-9 shrink-0 items-center justify-center",
2718
2951
  children: [
2719
- header && /* @__PURE__ */ jsx40("span", { className: "transition-opacity group-hover:opacity-0", children: resolve(header, collapsed) }),
2720
- /* @__PURE__ */ jsx40(
2721
- PanelLeftOpen,
2952
+ header && /* @__PURE__ */ jsx43("span", { className: "transition-opacity group-hover:opacity-0", children: resolve(header, collapsed) }),
2953
+ /* @__PURE__ */ jsx43(
2954
+ ChevronDoubleRightIcon,
2722
2955
  {
2723
2956
  className: "absolute h-4 w-4 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100",
2724
2957
  "aria-hidden": true
@@ -2727,22 +2960,22 @@ function Sidebar({
2727
2960
  ]
2728
2961
  }
2729
2962
  )
2730
- ) : /* @__PURE__ */ jsxs22(Fragment4, { children: [
2731
- header && /* @__PURE__ */ jsx40("div", { className: "min-w-0 flex-1", children: resolve(header, collapsed) }),
2732
- onCollapsedChange && /* @__PURE__ */ jsx40(
2963
+ ) : /* @__PURE__ */ jsxs25(Fragment5, { children: [
2964
+ header && /* @__PURE__ */ jsx43("div", { className: "min-w-0 flex-1", children: resolve(header, collapsed) }),
2965
+ onCollapsedChange && /* @__PURE__ */ jsx43(
2733
2966
  "button",
2734
2967
  {
2735
2968
  type: "button",
2736
2969
  onClick: () => onCollapsedChange(!collapsed),
2737
2970
  "aria-label": "Collapse sidebar",
2738
2971
  className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground",
2739
- children: /* @__PURE__ */ jsx40(PanelLeftClose, { className: "h-4 w-4", "aria-hidden": true })
2972
+ children: /* @__PURE__ */ jsx43(ChevronDoubleLeftIcon, { className: "h-4 w-4", "aria-hidden": true })
2740
2973
  }
2741
2974
  )
2742
2975
  ] }) }),
2743
- /* @__PURE__ */ jsx40(SidebarNav, { children }),
2744
- footer && /* @__PURE__ */ jsx40("div", { className: "border-t border-border/50 px-2 py-2", children: resolve(footer, collapsed) }),
2745
- resizable && !collapsed && /* @__PURE__ */ jsx40(
2976
+ /* @__PURE__ */ jsx43(SidebarNav, { children }),
2977
+ footer && /* @__PURE__ */ jsx43("div", { className: "border-t border-border/50 px-2 py-2", children: resolve(footer, collapsed) }),
2978
+ resizable && !collapsed && /* @__PURE__ */ jsx43(
2746
2979
  "div",
2747
2980
  {
2748
2981
  onPointerDown: handlePointerDown,
@@ -2758,8 +2991,8 @@ function Sidebar({
2758
2991
  }
2759
2992
  function SidebarNav({ children, className, ...rest }) {
2760
2993
  const ref = useRef6(null);
2761
- const [showFade, setShowFade] = useState11(false);
2762
- useEffect5(() => {
2994
+ const [showFade, setShowFade] = useState12(false);
2995
+ useEffect6(() => {
2763
2996
  const el = ref.current;
2764
2997
  if (!el) return;
2765
2998
  const update = () => setShowFade(el.scrollHeight - el.scrollTop - el.clientHeight > 1);
@@ -2772,8 +3005,8 @@ function SidebarNav({ children, className, ...rest }) {
2772
3005
  observer.disconnect();
2773
3006
  };
2774
3007
  }, []);
2775
- return /* @__PURE__ */ jsxs22("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
2776
- /* @__PURE__ */ jsx40(
3008
+ return /* @__PURE__ */ jsxs25("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
3009
+ /* @__PURE__ */ jsx43(
2777
3010
  "div",
2778
3011
  {
2779
3012
  ref,
@@ -2782,7 +3015,7 @@ function SidebarNav({ children, className, ...rest }) {
2782
3015
  children
2783
3016
  }
2784
3017
  ),
2785
- showFade && /* @__PURE__ */ jsx40(
3018
+ showFade && /* @__PURE__ */ jsx43(
2786
3019
  "div",
2787
3020
  {
2788
3021
  className: "pointer-events-none absolute right-0 bottom-0 left-0 h-6 bg-gradient-to-t from-sidebar to-transparent",
@@ -2793,11 +3026,11 @@ function SidebarNav({ children, className, ...rest }) {
2793
3026
  }
2794
3027
 
2795
3028
  // src/patterns/ai/AiButton.tsx
2796
- import { Sparkles } from "lucide-react";
3029
+ import { SparklesIcon } from "@heroicons/react/24/outline";
2797
3030
  import { forwardRef as forwardRef17 } from "react";
2798
- import { jsx as jsx41, jsxs as jsxs23 } from "react/jsx-runtime";
3031
+ import { jsx as jsx44, jsxs as jsxs26 } from "react/jsx-runtime";
2799
3032
  var AiButton = forwardRef17(
2800
- ({ variant = "ai-subtle", loading = false, icon: Icon2 = Sparkles, disabled, children, ...props }, ref) => /* @__PURE__ */ jsxs23(
3033
+ ({ variant = "ai-subtle", loading = false, icon: Icon2 = SparklesIcon, disabled, children, ...props }, ref) => /* @__PURE__ */ jsxs26(
2801
3034
  Button,
2802
3035
  {
2803
3036
  ref,
@@ -2806,7 +3039,7 @@ var AiButton = forwardRef17(
2806
3039
  "aria-busy": loading || void 0,
2807
3040
  ...props,
2808
3041
  children: [
2809
- loading ? /* @__PURE__ */ jsx41(LoadingSpinner, { size: "sm", className: "[&_svg]:text-current" }) : /* @__PURE__ */ jsx41(Icon2, { className: "h-4 w-4", "aria-hidden": "true" }),
3042
+ loading ? /* @__PURE__ */ jsx44(LoadingSpinner, { size: "sm", className: "[&_svg]:text-current" }) : /* @__PURE__ */ jsx44(Icon2, { className: "h-4 w-4", "aria-hidden": "true" }),
2810
3043
  children
2811
3044
  ]
2812
3045
  }
@@ -2815,9 +3048,9 @@ var AiButton = forwardRef17(
2815
3048
  AiButton.displayName = "AiButton";
2816
3049
 
2817
3050
  // src/patterns/ai/AiExplainButton.tsx
2818
- import { RefreshCw, Sparkles as Sparkles2 } from "lucide-react";
2819
- import { useState as useState12 } from "react";
2820
- import { jsx as jsx42, jsxs as jsxs24 } from "react/jsx-runtime";
3051
+ import { SparklesIcon as SparklesIcon2 } from "@heroicons/react/24/outline";
3052
+ import { useState as useState13 } from "react";
3053
+ import { jsx as jsx45, jsxs as jsxs27 } from "react/jsx-runtime";
2821
3054
  function AiExplainButton({
2822
3055
  onExplain,
2823
3056
  label = "Explain",
@@ -2827,10 +3060,10 @@ function AiExplainButton({
2827
3060
  size = "sm",
2828
3061
  ...props
2829
3062
  }) {
2830
- const [open, setOpen] = useState12(false);
2831
- const [loading, setLoading] = useState12(false);
2832
- const [content, setContent] = useState12(null);
2833
- const [error, setError] = useState12(null);
3063
+ const [open, setOpen] = useState13(false);
3064
+ const [loading, setLoading] = useState13(false);
3065
+ const [content, setContent] = useState13(null);
3066
+ const [error, setError] = useState13(null);
2834
3067
  const load = async () => {
2835
3068
  setLoading(true);
2836
3069
  setError(null);
@@ -2846,30 +3079,32 @@ function AiExplainButton({
2846
3079
  setOpen(next);
2847
3080
  if (next && content === null && error === null && !loading) void load();
2848
3081
  };
2849
- return /* @__PURE__ */ jsxs24(Popover, { open, onOpenChange: handleOpenChange, children: [
2850
- /* @__PURE__ */ jsx42(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(AiButton, { size, ...props, children: label }) }),
2851
- /* @__PURE__ */ jsxs24(PopoverContent, { align, className: contentClassName, children: [
2852
- /* @__PURE__ */ jsxs24("p", { className: "mb-2 flex items-center gap-1.5 text-sm font-semibold", children: [
2853
- /* @__PURE__ */ jsx42(Sparkles2, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
3082
+ return /* @__PURE__ */ jsxs27(Popover, { open, onOpenChange: handleOpenChange, children: [
3083
+ /* @__PURE__ */ jsx45(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx45(AiButton, { size, ...props, children: label }) }),
3084
+ /* @__PURE__ */ jsxs27(PopoverContent, { align, className: contentClassName, children: [
3085
+ /* @__PURE__ */ jsxs27("p", { className: "mb-2 flex items-center gap-1.5 text-sm font-semibold", children: [
3086
+ /* @__PURE__ */ jsx45(SparklesIcon2, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
2854
3087
  title ?? label
2855
3088
  ] }),
2856
- loading ? /* @__PURE__ */ jsx42(LoadingSpinner, { size: "sm", label: "Thinking\u2026", className: "text-sm text-muted-foreground" }) : error ? /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-start gap-2", children: [
2857
- /* @__PURE__ */ jsx42("div", { role: "alert", className: "w-full", children: /* @__PURE__ */ jsx42(AlertBox, { variant: "error", children: error }) }),
2858
- /* @__PURE__ */ jsxs24(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void load(), children: [
2859
- /* @__PURE__ */ jsx42(RefreshCw, { className: "h-4 w-4", "aria-hidden": "true" }),
2860
- "Try again"
2861
- ] })
2862
- ] }) : /* @__PURE__ */ jsx42("div", { className: "max-h-80 overflow-y-auto text-sm leading-relaxed", children: content })
3089
+ loading ? /* @__PURE__ */ jsx45(LoadingSpinner, { size: "sm", label: "Thinking\u2026", className: "text-sm text-muted-foreground" }) : error ? /* @__PURE__ */ jsx45(
3090
+ ErrorState,
3091
+ {
3092
+ variant: "compact",
3093
+ error,
3094
+ onRetry: () => void load(),
3095
+ labels: { title: "Something went wrong", retry: "Try again" }
3096
+ }
3097
+ ) : /* @__PURE__ */ jsx45("div", { className: "max-h-80 overflow-y-auto text-sm leading-relaxed", children: content })
2863
3098
  ] })
2864
3099
  ] });
2865
3100
  }
2866
3101
 
2867
3102
  // src/patterns/ai/VoiceInputButton.tsx
2868
- import { Mic, MicOff } from "lucide-react";
3103
+ import { MicrophoneIcon, SlashIcon } from "@heroicons/react/24/outline";
2869
3104
  import { forwardRef as forwardRef18 } from "react";
2870
3105
 
2871
3106
  // src/patterns/ai/useSpeechRecognition.ts
2872
- import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef7, useState as useState13 } from "react";
3107
+ import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef7, useState as useState14 } from "react";
2873
3108
  function getCtor() {
2874
3109
  if (typeof window === "undefined") return void 0;
2875
3110
  const w = window;
@@ -2902,9 +3137,9 @@ function useSpeechRecognition({
2902
3137
  onError,
2903
3138
  engine
2904
3139
  } = {}) {
2905
- const [listening, setListening] = useState13(false);
2906
- const [interim, setInterim] = useState13("");
2907
- const [error, setError] = useState13(null);
3140
+ const [listening, setListening] = useState14(false);
3141
+ const [interim, setInterim] = useState14("");
3142
+ const [error, setError] = useState14(null);
2908
3143
  const recognitionRef = useRef7(null);
2909
3144
  const onResultRef = useRef7(onResult);
2910
3145
  const onErrorRef = useRef7(onError);
@@ -2953,12 +3188,12 @@ function useSpeechRecognition({
2953
3188
  if (recognitionRef.current) stop();
2954
3189
  else start();
2955
3190
  }, [start, stop]);
2956
- useEffect6(() => () => recognitionRef.current?.abort(), []);
3191
+ useEffect7(() => () => recognitionRef.current?.abort(), []);
2957
3192
  return { supported, listening, interim, error, start, stop, toggle };
2958
3193
  }
2959
3194
 
2960
3195
  // src/patterns/ai/VoiceInputButton.tsx
2961
- import { jsx as jsx43, jsxs as jsxs25 } from "react/jsx-runtime";
3196
+ import { jsx as jsx46, jsxs as jsxs28 } from "react/jsx-runtime";
2962
3197
  var VoiceInputButton = forwardRef18(
2963
3198
  ({
2964
3199
  onTranscript,
@@ -2984,8 +3219,8 @@ var VoiceInputButton = forwardRef18(
2984
3219
  return (
2985
3220
  // `title` lives on the wrapper, not the button: buttonVariants sets
2986
3221
  // `disabled:pointer-events-none`, so a disabled button never shows its own.
2987
- /* @__PURE__ */ jsxs25("span", { className: "inline-flex min-w-0 items-center gap-2", title: supported ? void 0 : unsupportedTitle, children: [
2988
- /* @__PURE__ */ jsxs25(
3222
+ /* @__PURE__ */ jsxs28("span", { className: "inline-flex min-w-0 items-center gap-2", title: supported ? void 0 : unsupportedTitle, children: [
3223
+ /* @__PURE__ */ jsxs28(
2989
3224
  Button,
2990
3225
  {
2991
3226
  ref,
@@ -3002,12 +3237,25 @@ var VoiceInputButton = forwardRef18(
3002
3237
  ),
3003
3238
  ...props,
3004
3239
  children: [
3005
- supported ? /* @__PURE__ */ jsx43(Mic, { className: cn("h-4 w-4", listening && "animate-pulse motion-reduce:animate-none"), "aria-hidden": "true" }) : /* @__PURE__ */ jsx43(MicOff, { className: "h-4 w-4", "aria-hidden": "true" }),
3240
+ supported ? /* @__PURE__ */ jsx46(
3241
+ MicrophoneIcon,
3242
+ {
3243
+ className: cn("h-4 w-4", listening && "animate-pulse motion-reduce:animate-none"),
3244
+ "aria-hidden": "true"
3245
+ }
3246
+ ) : (
3247
+ // heroicons has no muted-mic glyph -- MicrophoneIcon plus SlashIcon
3248
+ // (same 24x24 viewBox/stroke) layered on top approximates one.
3249
+ /* @__PURE__ */ jsxs28("span", { className: "relative inline-flex h-4 w-4", "aria-hidden": "true", children: [
3250
+ /* @__PURE__ */ jsx46(MicrophoneIcon, { className: "h-4 w-4" }),
3251
+ /* @__PURE__ */ jsx46(SlashIcon, { className: "absolute inset-0 h-4 w-4" })
3252
+ ] })
3253
+ ),
3006
3254
  label
3007
3255
  ]
3008
3256
  }
3009
3257
  ),
3010
- showInterim && interim ? /* @__PURE__ */ jsx43("span", { "aria-live": "polite", className: "truncate text-sm text-muted-foreground italic", children: interim }) : null
3258
+ showInterim && interim ? /* @__PURE__ */ jsx46("span", { "aria-live": "polite", className: "truncate text-sm text-muted-foreground italic", children: interim }) : null
3011
3259
  ] })
3012
3260
  );
3013
3261
  }
@@ -3015,9 +3263,9 @@ var VoiceInputButton = forwardRef18(
3015
3263
  VoiceInputButton.displayName = "VoiceInputButton";
3016
3264
 
3017
3265
  // src/patterns/ai/VoiceTranscript.tsx
3018
- import { Undo2, Wand2 } from "lucide-react";
3019
- import { useState as useState14 } from "react";
3020
- import { jsx as jsx44, jsxs as jsxs26 } from "react/jsx-runtime";
3266
+ import { ArrowUturnLeftIcon, SparklesIcon as SparklesIcon3 } from "@heroicons/react/24/outline";
3267
+ import { useState as useState15 } from "react";
3268
+ import { jsx as jsx47, jsxs as jsxs29 } from "react/jsx-runtime";
3021
3269
  function VoiceTranscript({
3022
3270
  value,
3023
3271
  onChange,
@@ -3031,9 +3279,9 @@ function VoiceTranscript({
3031
3279
  className,
3032
3280
  ...props
3033
3281
  }) {
3034
- const [loading, setLoading] = useState14(false);
3035
- const [error, setError] = useState14(null);
3036
- const [previous, setPrevious] = useState14(null);
3282
+ const [loading, setLoading] = useState15(false);
3283
+ const [error, setError] = useState15(null);
3284
+ const [previous, setPrevious] = useState15(null);
3037
3285
  const append = (chunk) => {
3038
3286
  onChange(value ? `${value.trimEnd()} ${chunk}` : chunk);
3039
3287
  };
@@ -3057,8 +3305,8 @@ function VoiceTranscript({
3057
3305
  onChange(previous);
3058
3306
  setPrevious(null);
3059
3307
  };
3060
- return /* @__PURE__ */ jsxs26("div", { className: cn("flex flex-col gap-2", className), ...props, children: [
3061
- /* @__PURE__ */ jsx44(
3308
+ return /* @__PURE__ */ jsxs29("div", { className: cn("flex flex-col gap-2", className), ...props, children: [
3309
+ /* @__PURE__ */ jsx47(
3062
3310
  Textarea,
3063
3311
  {
3064
3312
  value,
@@ -3069,8 +3317,8 @@ function VoiceTranscript({
3069
3317
  "aria-busy": loading || void 0
3070
3318
  }
3071
3319
  ),
3072
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-wrap items-center gap-2", children: [
3073
- /* @__PURE__ */ jsx44(
3320
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap items-center gap-2", children: [
3321
+ /* @__PURE__ */ jsx47(
3074
3322
  VoiceInputButton,
3075
3323
  {
3076
3324
  onTranscript: append,
@@ -3083,35 +3331,35 @@ function VoiceTranscript({
3083
3331
  disabled: disabled || loading
3084
3332
  }
3085
3333
  ),
3086
- onTransform ? /* @__PURE__ */ jsx44(
3334
+ onTransform ? /* @__PURE__ */ jsx47(
3087
3335
  AiButton,
3088
3336
  {
3089
3337
  variant: "ai",
3090
3338
  size: "sm",
3091
- icon: Wand2,
3339
+ icon: SparklesIcon3,
3092
3340
  loading,
3093
3341
  disabled: disabled || value.trim().length === 0,
3094
3342
  onClick: () => void transform(),
3095
3343
  children: transformLabel
3096
3344
  }
3097
3345
  ) : null,
3098
- previous !== null && !loading ? /* @__PURE__ */ jsxs26(Button, { type: "button", variant: "ghost", size: "sm", onClick: undo, children: [
3099
- /* @__PURE__ */ jsx44(Undo2, { className: "h-4 w-4", "aria-hidden": "true" }),
3346
+ previous !== null && !loading ? /* @__PURE__ */ jsxs29(Button, { type: "button", variant: "ghost", size: "sm", onClick: undo, children: [
3347
+ /* @__PURE__ */ jsx47(ArrowUturnLeftIcon, { className: "h-4 w-4", "aria-hidden": "true" }),
3100
3348
  "Undo"
3101
3349
  ] }) : null
3102
3350
  ] }),
3103
3351
  error ? (
3104
3352
  // AlertBox has no `role` prop, so the live region wraps it; same shape
3105
3353
  // a consuming app's own form errors take.
3106
- /* @__PURE__ */ jsx44("div", { role: "alert", children: /* @__PURE__ */ jsx44(AlertBox, { variant: "error", children: error }) })
3354
+ /* @__PURE__ */ jsx47("div", { role: "alert", children: /* @__PURE__ */ jsx47(AlertBox, { variant: "error", children: error }) })
3107
3355
  ) : null
3108
3356
  ] });
3109
3357
  }
3110
3358
 
3111
3359
  // src/patterns/stepper/Stepper.tsx
3112
- import { useEffect as useEffect7, useRef as useRef8 } from "react";
3113
- import { Check as Check5, Plus } from "lucide-react";
3114
- import { jsx as jsx45, jsxs as jsxs27 } from "react/jsx-runtime";
3360
+ import { useEffect as useEffect8, useRef as useRef8 } from "react";
3361
+ import { CheckIcon as CheckIcon5, PlusIcon } from "@heroicons/react/24/outline";
3362
+ import { jsx as jsx48, jsxs as jsxs30 } from "react/jsx-runtime";
3115
3363
  function Stepper({
3116
3364
  step,
3117
3365
  maxStep,
@@ -3124,7 +3372,7 @@ function Stepper({
3124
3372
  newTestId
3125
3373
  }) {
3126
3374
  const stepRefs = useRef8(/* @__PURE__ */ new Map());
3127
- useEffect7(() => {
3375
+ useEffect8(() => {
3128
3376
  const activeStep = stepRefs.current.get(step);
3129
3377
  activeStep?.scrollIntoView({ block: "nearest", inline: "center" });
3130
3378
  }, [step]);
@@ -3132,19 +3380,19 @@ function Stepper({
3132
3380
  // onNew is pinned outside the horizontally-scrolling region below (a sibling of
3133
3381
  // it, not a child) so its own edge never scrolls off-screen along with the
3134
3382
  // later steps once the scroller's min-width doesn't fit the viewport.
3135
- /* @__PURE__ */ jsxs27("div", { className: "flex w-full shrink-0 items-center gap-2", children: [
3136
- /* @__PURE__ */ jsx45("nav", { "aria-label": navLabel, className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx45(
3383
+ /* @__PURE__ */ jsxs30("div", { className: "flex w-full shrink-0 items-center gap-2", children: [
3384
+ /* @__PURE__ */ jsx48("nav", { "aria-label": navLabel, className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx48(
3137
3385
  "div",
3138
3386
  {
3139
3387
  "data-testid": scrollTestId,
3140
3388
  className: "flex w-full items-center gap-0 overflow-x-auto px-2 py-1",
3141
- children: /* @__PURE__ */ jsx45("ol", { className: "flex min-w-[700px] flex-1 items-start", children: steps.map(({ n, label, phase }, i) => {
3389
+ children: /* @__PURE__ */ jsx48("ol", { className: "flex min-w-[700px] flex-1 items-start", children: steps.map(({ n, label, phase }, i) => {
3142
3390
  const done = step > n;
3143
3391
  const active = step === n;
3144
3392
  const navigable = n <= maxStep && n !== step;
3145
3393
  const last = i === steps.length - 1;
3146
- return /* @__PURE__ */ jsxs27("li", { className: cn("flex items-start", !last && "flex-1"), children: [
3147
- /* @__PURE__ */ jsxs27(
3394
+ return /* @__PURE__ */ jsxs30("li", { className: cn("flex items-start", !last && "flex-1"), children: [
3395
+ /* @__PURE__ */ jsxs30(
3148
3396
  "button",
3149
3397
  {
3150
3398
  ref: (element) => {
@@ -3160,17 +3408,17 @@ function Stepper({
3160
3408
  navigable ? "cursor-pointer hover:opacity-80" : "cursor-default"
3161
3409
  ),
3162
3410
  children: [
3163
- /* @__PURE__ */ jsx45(
3411
+ /* @__PURE__ */ jsx48(
3164
3412
  "div",
3165
3413
  {
3166
3414
  className: cn(
3167
3415
  "flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[11px] font-bold transition-colors",
3168
3416
  done ? "bg-primary/15 text-primary" : active ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"
3169
3417
  ),
3170
- children: done ? /* @__PURE__ */ jsx45(Check5, { className: "h-3 w-3" }) : n
3418
+ children: done ? /* @__PURE__ */ jsx48(CheckIcon5, { className: "h-3 w-3" }) : n
3171
3419
  }
3172
3420
  ),
3173
- /* @__PURE__ */ jsx45(
3421
+ /* @__PURE__ */ jsx48(
3174
3422
  "span",
3175
3423
  {
3176
3424
  className: cn(
@@ -3180,11 +3428,11 @@ function Stepper({
3180
3428
  children: label
3181
3429
  }
3182
3430
  ),
3183
- /* @__PURE__ */ jsx45("span", { className: "text-[9px] tracking-[0.5px] text-muted-foreground/50 uppercase", children: phase })
3431
+ /* @__PURE__ */ jsx48("span", { className: "text-[9px] tracking-[0.5px] text-muted-foreground/50 uppercase", children: phase })
3184
3432
  ]
3185
3433
  }
3186
3434
  ),
3187
- !last && /* @__PURE__ */ jsx45(
3435
+ !last && /* @__PURE__ */ jsx48(
3188
3436
  "div",
3189
3437
  {
3190
3438
  className: cn(
@@ -3197,7 +3445,7 @@ function Stepper({
3197
3445
  }) })
3198
3446
  }
3199
3447
  ) }),
3200
- onNew && /* @__PURE__ */ jsxs27(
3448
+ onNew && /* @__PURE__ */ jsxs30(
3201
3449
  "button",
3202
3450
  {
3203
3451
  "data-testid": newTestId,
@@ -3205,7 +3453,7 @@ function Stepper({
3205
3453
  title: newLabel,
3206
3454
  className: "flex shrink-0 items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-[12px] font-semibold text-foreground transition-colors hover:bg-muted/50",
3207
3455
  children: [
3208
- /* @__PURE__ */ jsx45(Plus, { className: "h-3.5 w-3.5" }),
3456
+ /* @__PURE__ */ jsx48(PlusIcon, { className: "h-3.5 w-3.5" }),
3209
3457
  newLabel
3210
3458
  ]
3211
3459
  }
@@ -3213,10 +3461,660 @@ function Stepper({
3213
3461
  ] })
3214
3462
  );
3215
3463
  }
3464
+
3465
+ // src/patterns/animated-brand/AnimatedBrand.tsx
3466
+ import {
3467
+ useEffect as useEffect9,
3468
+ useRef as useRef9,
3469
+ useState as useState16
3470
+ } from "react";
3471
+
3472
+ // src/patterns/animated-brand/brandMotion.ts
3473
+ var BRAND_ANIMATIONS = [
3474
+ { id: "bounce", label: "Bounce home" },
3475
+ { id: "orbit", label: "Orbit and settle" },
3476
+ { id: "impact", label: "Shot in, boom" },
3477
+ { id: "liquid", label: "Liquid split" },
3478
+ { id: "signature", label: "Solid to signature" },
3479
+ { id: "burst", label: "Big bang, small dot" },
3480
+ { id: "gravity", label: "Gravity press" }
3481
+ ];
3482
+ function playBrandMotion(p, name, onComplete) {
3483
+ const list = [];
3484
+ if (!p.animate || window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
3485
+ onComplete?.();
3486
+ return () => {
3487
+ };
3488
+ }
3489
+ const accent2 = "var(--bms-brand-dot)";
3490
+ const q = (s) => {
3491
+ const element = p.querySelector(s);
3492
+ if (!element) throw new Error(`Missing logo part: ${s}`);
3493
+ return element;
3494
+ }, logo = q('[data-logo-part="logo"]'), ring = q('[data-logo-part="ring"]'), bead = q('[data-logo-part="bead"]'), tail = q('[data-logo-part="tail"]'), core = q('[data-logo-part="core"]');
3495
+ const unit = parseFloat(getComputedStyle(logo).fontSize) || 48;
3496
+ const a = (el, k, d = 2e3, delay = 0) => {
3497
+ const v = el.animate(k, {
3498
+ duration: d,
3499
+ delay,
3500
+ iterations: 1,
3501
+ fill: "both",
3502
+ easing: "linear"
3503
+ });
3504
+ list.push(v);
3505
+ return v;
3506
+ };
3507
+ const t = (x, y, sx = 1, sy = sx) => `translate(${x}em,${y}em) scale(${sx},${sy})`;
3508
+ const points = (items) => items.map(([offset, x, y, sx = 1, sy = sx, color = accent2]) => ({
3509
+ offset,
3510
+ transform: t(x, y, sx, sy),
3511
+ background: color
3512
+ }));
3513
+ const shock = (delay, strength = 1) => p.querySelectorAll('[data-logo-part="echo"]').forEach((e, j) => {
3514
+ a(
3515
+ e,
3516
+ [
3517
+ { opacity: 0, transform: "scale(1)" },
3518
+ { opacity: 0.48 * strength, transform: "scale(1.6)", offset: 0.08 },
3519
+ { opacity: 0, transform: `scale(${j ? 8 : 6})`, offset: 1 }
3520
+ ],
3521
+ 650,
3522
+ delay + j * 110
3523
+ );
3524
+ });
3525
+ const sparks = (delay, out = 1) => p.querySelectorAll('[data-logo-part="particle"]').forEach((e, j) => {
3526
+ const angle = j * Math.PI / 4, x = Math.cos(angle) * out, y = Math.sin(angle) * out;
3527
+ a(
3528
+ e,
3529
+ [
3530
+ { opacity: 0, transform: t(0, 0, 0.2) },
3531
+ { opacity: 0.85, transform: t(x * 0.3, y * 0.3), offset: 0.12 },
3532
+ { opacity: 0, transform: t(x, y, 0.25), offset: 1 }
3533
+ ],
3534
+ 650,
3535
+ delay
3536
+ );
3537
+ });
3538
+ const impact = (start, duration) => {
3539
+ a(
3540
+ ring,
3541
+ [
3542
+ { offset: 0, transform: "scale(1)" },
3543
+ { offset: start - 0.015, transform: "scale(1)" },
3544
+ { offset: start + 0.045, transform: "scale(.82,1.12)" },
3545
+ { offset: start + 0.12, transform: "scale(1.06,.97)" },
3546
+ { offset: start + 0.24, transform: "scale(1)" },
3547
+ { offset: 1, transform: "scale(1)" }
3548
+ ],
3549
+ duration
3550
+ );
3551
+ a(
3552
+ tail,
3553
+ [
3554
+ { offset: 0, transform: "translateX(0)" },
3555
+ { offset: start, transform: "translateX(0)" },
3556
+ { offset: start + 0.04, transform: "translateX(-.065em)" },
3557
+ { offset: start + 0.14, transform: "translateX(.018em)" },
3558
+ { offset: start + 0.24, transform: "translateX(0)" },
3559
+ { offset: 1, transform: "translateX(0)" }
3560
+ ],
3561
+ duration
3562
+ );
3563
+ };
3564
+ if (name === "bounce") {
3565
+ const beadRect = bead.getBoundingClientRect();
3566
+ const viewportUnitX = beadRect.width > 0 ? beadRect.width / 0.2 : unit;
3567
+ const viewportUnitY = beadRect.height > 0 ? beadRect.height / 0.2 : unit;
3568
+ const originX = beadRect.x + beadRect.width / 2;
3569
+ const originY = beadRect.y + beadRect.height / 2;
3570
+ const letters = Array.from(
3571
+ p.querySelectorAll("[data-brand-letter]")
3572
+ ).reverse();
3573
+ const baseline = p.querySelector("[data-brand-baseline]")?.getBoundingClientRect().top ?? originY;
3574
+ const pen = typeof CanvasRenderingContext2D !== "undefined" ? document.createElement("canvas").getContext("2d") : null;
3575
+ if (pen) pen.font = getComputedStyle(logo).font;
3576
+ const stops = letters.length ? letters.map((letter) => {
3577
+ const rect = letter.getBoundingClientRect();
3578
+ const ascent = pen?.measureText(letter.textContent ?? "").actualBoundingBoxAscent ?? unit * 0.7;
3579
+ return {
3580
+ x: (rect.x + rect.width / 2 - originX) / viewportUnitX,
3581
+ y: (baseline - originY) / viewportUnitY - ascent / unit - 0.1
3582
+ };
3583
+ }) : [
3584
+ { x: -1.1, y: -0.7 },
3585
+ { x: -0.3, y: -0.4 },
3586
+ { x: 0.3, y: -0.4 }
3587
+ ];
3588
+ const duration = 1e3 + stops.length * 340;
3589
+ let from = { x: stops[0].x + 0.5, y: stops[0].y - 0.65 };
3590
+ const frames = [{ offset: 0, transform: t(from.x, from.y) }];
3591
+ const destinations = [...stops, { x: 0, y: 0 }];
3592
+ const jumpEnd = 0.94;
3593
+ destinations.forEach((to, index) => {
3594
+ const start = index / destinations.length * jumpEnd;
3595
+ const length = jumpEnd / destinations.length;
3596
+ for (let k = 1; k <= 10; k++) {
3597
+ const u = k / 10;
3598
+ frames.push({
3599
+ offset: start + length * u * 0.87,
3600
+ transform: t(
3601
+ from.x + (to.x - from.x) * u,
3602
+ from.y + (to.y - from.y) * u - 1.6 * u * (1 - u)
3603
+ )
3604
+ });
3605
+ }
3606
+ frames.push({
3607
+ offset: start + length * 0.94,
3608
+ transform: t(to.x, to.y + 0.018, 1.15, 0.82)
3609
+ });
3610
+ frames.push({ offset: start + length, transform: t(to.x, to.y) });
3611
+ from = to;
3612
+ });
3613
+ frames.push({ offset: 1, transform: t(0, 0) });
3614
+ a(bead, frames, duration);
3615
+ shock(duration * 0.94, 0.5);
3616
+ } else if (name === "orbit") {
3617
+ const frames = [];
3618
+ for (let step = 0; step <= 72; step++) {
3619
+ const u = step / 72;
3620
+ const angle = -Math.PI / 2 + u * Math.PI * 3.7;
3621
+ const radius = 0.683 * (1 - u ** 2.4);
3622
+ frames.push({
3623
+ offset: u,
3624
+ transform: t(Math.cos(angle) * radius, Math.sin(angle) * radius)
3625
+ });
3626
+ }
3627
+ a(bead, frames, 2500);
3628
+ a(
3629
+ ring,
3630
+ [
3631
+ { transform: "scale(1)" },
3632
+ { offset: 0.8, transform: "scale(1.06)" },
3633
+ { offset: 1, transform: "scale(1)" }
3634
+ ],
3635
+ 2500
3636
+ );
3637
+ shock(2400, 0.5);
3638
+ } else if (name === "impact") {
3639
+ const d = 1650;
3640
+ a(
3641
+ bead,
3642
+ points([
3643
+ [0, 6.5, 0, 4, 0.38],
3644
+ [0.2, 6.5, 0, 4, 0.38],
3645
+ [0.3, 1.5, 0, 4, 0.38],
3646
+ [0.33, 0, 0, 0.55, 1.55],
3647
+ [0.39, -0.09, 0, 1.35, 0.72],
3648
+ [0.48, 0.035, 0, 0.93, 1.06],
3649
+ [0.65, 0, 0, 1, 1],
3650
+ [1, 0, 0, 1, 1]
3651
+ ]),
3652
+ d
3653
+ );
3654
+ a(
3655
+ q('[data-logo-part="trail"]'),
3656
+ [
3657
+ { opacity: 0, transform: t(6.5, 0, 2, 1) },
3658
+ { opacity: 0, transform: t(6.5, 0, 2, 1), offset: 0.2 },
3659
+ { opacity: 0.6, transform: t(0.5, 0, 1.8, 1), offset: 0.32 },
3660
+ { opacity: 0, transform: t(0, 0, 0.1, 1), offset: 0.39 },
3661
+ { opacity: 0, offset: 1 }
3662
+ ],
3663
+ d
3664
+ );
3665
+ impact(0.33, d);
3666
+ shock(545);
3667
+ sparks(545, 0.94);
3668
+ } else if (name === "liquid") {
3669
+ const d = 2400;
3670
+ a(
3671
+ bead,
3672
+ points([
3673
+ [0, 0, 0, 4],
3674
+ [0.15, 0, 0, 4],
3675
+ [0.3, 0, 0, 5.2, 2.7],
3676
+ [0.43, 0, 0, 2.8, 4.4],
3677
+ [0.58, 0, 0, 1.6, 2],
3678
+ [0.74, 0, 0, 0.85, 1.15],
3679
+ [0.88, 0, 0, 1.06, 0.94],
3680
+ [1, 0, 0, 1]
3681
+ ]),
3682
+ d
3683
+ );
3684
+ a(
3685
+ ring,
3686
+ [
3687
+ { offset: 0, opacity: 0, transform: "scale(.2) rotate(-35deg)" },
3688
+ { offset: 0.36, opacity: 0, transform: "scale(.2) rotate(-35deg)" },
3689
+ { offset: 0.63, opacity: 1, transform: "scale(1.1,.9) rotate(8deg)" },
3690
+ { offset: 0.8, opacity: 1, transform: "scale(.97,1.03) rotate(-2deg)" },
3691
+ { offset: 1, opacity: 1, transform: "scale(1) rotate(0deg)" }
3692
+ ],
3693
+ d
3694
+ );
3695
+ a(
3696
+ tail,
3697
+ [
3698
+ { offset: 0, opacity: 0, transform: "translateX(-.25em)" },
3699
+ { offset: 0.35, opacity: 0, transform: "translateX(-.25em)" },
3700
+ { offset: 0.72, opacity: 1, transform: "translateX(.025em)" },
3701
+ { offset: 1, opacity: 1, transform: "translateX(0)" }
3702
+ ],
3703
+ d
3704
+ );
3705
+ } else if (name === "gravity") {
3706
+ const d = 2600;
3707
+ a(
3708
+ bead,
3709
+ points([
3710
+ [0, 0, -1.15, 4],
3711
+ [0.12, 0, -1.15, 4],
3712
+ [0.24, 0, -0.88, 4],
3713
+ [0.34, 0, -0.35, 3.7, 4.3],
3714
+ [0.4, 0, 0.15, 5.1, 2.5],
3715
+ [0.49, 0, -0.32, 3.4, 4.2],
3716
+ [0.58, 0, 0.07, 4.4, 3.5],
3717
+ [0.67, 0, 0, 3.8, 4],
3718
+ [0.81, 0, 0, 0.78, 1.22],
3719
+ [0.91, 0, 0, 1.1, 0.9],
3720
+ [1, 0, 0, 1]
3721
+ ]),
3722
+ d
3723
+ );
3724
+ a(
3725
+ ring,
3726
+ [
3727
+ { offset: 0, opacity: 0, transform: "scale(.25)" },
3728
+ { offset: 0.64, opacity: 0, transform: "scale(.25)" },
3729
+ { offset: 0.81, opacity: 1, transform: "scale(1.12,.88)" },
3730
+ { offset: 0.92, opacity: 1, transform: "scale(.97,1.03)" },
3731
+ { offset: 1, opacity: 1, transform: "scale(1)" }
3732
+ ],
3733
+ d
3734
+ );
3735
+ a(
3736
+ tail,
3737
+ [
3738
+ { offset: 0, opacity: 0, transform: "translateY(.12em)" },
3739
+ { offset: 0.43, opacity: 0, transform: "translateY(.12em)" },
3740
+ { offset: 0.72, opacity: 1, transform: "translateY(0)" },
3741
+ { offset: 1, opacity: 1, transform: "translateY(0)" }
3742
+ ],
3743
+ d
3744
+ );
3745
+ shock(1040, 0.5);
3746
+ } else if (name === "signature") {
3747
+ const d = 2200;
3748
+ a(
3749
+ core,
3750
+ [
3751
+ { opacity: 1, background: accent2, transform: "scale(1)" },
3752
+ { opacity: 1, background: accent2, transform: "scale(1.08)", offset: 0.22 },
3753
+ { opacity: 1, background: accent2, transform: "scale(.22)", offset: 0.65 },
3754
+ { opacity: 1, background: accent2, transform: "scale(.25)", offset: 0.84 },
3755
+ { opacity: 0, background: accent2, transform: "scale(.25)", offset: 1 }
3756
+ ],
3757
+ d
3758
+ );
3759
+ a(
3760
+ bead,
3761
+ [{ opacity: 0 }, { opacity: 0, offset: 0.85 }, { opacity: 1, offset: 1 }],
3762
+ d
3763
+ );
3764
+ a(
3765
+ ring,
3766
+ [
3767
+ { opacity: 0, transform: "scale(.3)" },
3768
+ { opacity: 0, transform: "scale(.3)", offset: 0.25 },
3769
+ { opacity: 1, transform: "scale(1.04)", offset: 0.65 },
3770
+ { opacity: 1, transform: "scale(1)", offset: 0.83 },
3771
+ { opacity: 1, transform: "scale(1)", offset: 1 }
3772
+ ],
3773
+ d
3774
+ );
3775
+ a(
3776
+ tail,
3777
+ [
3778
+ { opacity: 0, transform: "translateX(-.18em)" },
3779
+ { opacity: 0, transform: "translateX(-.18em)", offset: 0.22 },
3780
+ { opacity: 1, transform: "translateX(0)", offset: 0.64 },
3781
+ { opacity: 1, transform: "translateX(0)", offset: 1 }
3782
+ ],
3783
+ d
3784
+ );
3785
+ } else {
3786
+ const d = 2500;
3787
+ a(
3788
+ core,
3789
+ [
3790
+ { opacity: 1, background: accent2, transform: "scale(.92)" },
3791
+ { opacity: 1, background: accent2, transform: "scale(1.14)", offset: 0.24 },
3792
+ { opacity: 0, background: accent2, transform: "scale(.1)", offset: 0.36 },
3793
+ { opacity: 0, offset: 1 }
3794
+ ],
3795
+ d
3796
+ );
3797
+ a(
3798
+ bead,
3799
+ [
3800
+ { opacity: 0, transform: "scale(.2)" },
3801
+ { opacity: 0, transform: "scale(.2)", offset: 0.69 },
3802
+ { opacity: 1, transform: "scale(1.2)", offset: 0.84 },
3803
+ { opacity: 1, transform: "scale(1)", offset: 1 }
3804
+ ],
3805
+ d
3806
+ );
3807
+ a(
3808
+ ring,
3809
+ [
3810
+ { opacity: 0, transform: "scale(.82)" },
3811
+ { opacity: 0, transform: "scale(.82)", offset: 0.34 },
3812
+ { opacity: 0.7, transform: "scale(1.04)", offset: 0.57 },
3813
+ { opacity: 1, transform: "scale(1)", offset: 0.82 },
3814
+ { opacity: 1, transform: "scale(1)", offset: 1 }
3815
+ ],
3816
+ d
3817
+ );
3818
+ a(
3819
+ tail,
3820
+ [
3821
+ { opacity: 0.15, transform: "translateX(-.06em)" },
3822
+ { opacity: 0.15, transform: "translateX(-.06em)", offset: 0.3 },
3823
+ { opacity: 1, transform: "translateX(0)", offset: 0.68 },
3824
+ { opacity: 1, transform: "translateX(0)", offset: 1 }
3825
+ ],
3826
+ d
3827
+ );
3828
+ p.querySelectorAll('[data-logo-part="particle"]').forEach((el, j) => {
3829
+ const angle = j * Math.PI / 4, x = Math.cos(angle) * 0.86, y = Math.sin(angle) * 0.86;
3830
+ a(
3831
+ el,
3832
+ [
3833
+ { opacity: 0, transform: t(0, 0, 0.2) },
3834
+ { opacity: 0, transform: t(0, 0, 0.2), offset: 0.27 },
3835
+ { opacity: 1, transform: t(x, y, 1.2), offset: 0.43 },
3836
+ { opacity: 1, transform: t(x * 0.85, y * 0.85), offset: 0.59 },
3837
+ { opacity: 0, transform: t(0, 0, 0.5), offset: 0.82 },
3838
+ { opacity: 0, transform: t(0, 0, 0.5), offset: 1 }
3839
+ ],
3840
+ d
3841
+ );
3842
+ });
3843
+ shock(1800, 0.6);
3844
+ }
3845
+ let cancelled = false;
3846
+ void Promise.all(list.map((animation) => animation.finished)).then(
3847
+ () => {
3848
+ if (!cancelled) {
3849
+ for (const animation of list) animation.cancel();
3850
+ onComplete?.();
3851
+ }
3852
+ },
3853
+ () => {
3854
+ }
3855
+ );
3856
+ return () => {
3857
+ cancelled = true;
3858
+ for (const animation of list) animation.cancel();
3859
+ };
3860
+ }
3861
+
3862
+ // src/patterns/animated-brand/AnimatedBrand.tsx
3863
+ import { jsx as jsx49, jsxs as jsxs31 } from "react/jsx-runtime";
3864
+ var absolute = {
3865
+ position: "absolute",
3866
+ borderRadius: "50%",
3867
+ pointerEvents: "none"
3868
+ };
3869
+ var centered = {
3870
+ ...absolute,
3871
+ width: ".2em",
3872
+ height: ".2em",
3873
+ left: "50%",
3874
+ top: "50%",
3875
+ margin: "-.1em"
3876
+ };
3877
+ var accent = "var(--bms-brand-dot)";
3878
+ function AnimatedBrand({
3879
+ product = "Brain",
3880
+ dotColor = "#e60028",
3881
+ textColor = "#929292",
3882
+ oneColor,
3883
+ productColor,
3884
+ ringColor,
3885
+ mode = "full",
3886
+ animation = "random",
3887
+ size = 48,
3888
+ autoPlay = true,
3889
+ replayKey,
3890
+ onComplete,
3891
+ className,
3892
+ style
3893
+ }) {
3894
+ const ref = useRef9(null);
3895
+ const completion = useRef9(onComplete);
3896
+ const [segmented, setSegmented] = useState16(null);
3897
+ useEffect9(() => {
3898
+ const letters2 = typeof Intl.Segmenter === "function" ? Array.from(new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(product), ({ segment }) => segment) : product ? [product] : [];
3899
+ setSegmented({ product, letters: letters2 });
3900
+ }, [product]);
3901
+ useEffect9(() => {
3902
+ completion.current = onComplete;
3903
+ }, [onComplete]);
3904
+ useEffect9(() => {
3905
+ const element = ref.current;
3906
+ if (!element || !autoPlay || segmented?.product !== product) return;
3907
+ let disposed = false;
3908
+ let stop;
3909
+ let completed = false;
3910
+ const finish = () => {
3911
+ if (!disposed && !completed) {
3912
+ completed = true;
3913
+ completion.current?.();
3914
+ }
3915
+ };
3916
+ const reduced = window.matchMedia("(prefers-reduced-motion: reduce)");
3917
+ const changed = () => {
3918
+ if (reduced.matches) {
3919
+ stop?.();
3920
+ finish();
3921
+ }
3922
+ };
3923
+ reduced.addEventListener("change", changed);
3924
+ const start = () => {
3925
+ if (disposed || completed) return;
3926
+ if (reduced.matches) {
3927
+ finish();
3928
+ return;
3929
+ }
3930
+ const choice = animation === "random" ? BRAND_ANIMATIONS[Math.floor(Math.random() * BRAND_ANIMATIONS.length)].id : animation;
3931
+ stop = playBrandMotion(element, choice, finish);
3932
+ };
3933
+ void (document.fonts?.ready ?? Promise.resolve()).then(start, start);
3934
+ return () => {
3935
+ disposed = true;
3936
+ stop?.();
3937
+ reduced.removeEventListener("change", changed);
3938
+ };
3939
+ }, [product, mode, animation, size, autoPlay, replayKey, segmented]);
3940
+ const tail = mode === "full" ? `ne${product}` : mode === "one" ? "ne" : "";
3941
+ const suffix = mode === "full" && product ? segmented?.product === product ? segmented.letters : [product] : [];
3942
+ const letters = tail ? ["n", "e", ...suffix] : [];
3943
+ const label = mode === "full" ? `One${product}` : mode === "one" ? "One" : "O";
3944
+ const wrapperStyle = {
3945
+ "--bms-brand-dot": dotColor,
3946
+ display: "inline-flex",
3947
+ fontSize: size,
3948
+ color: textColor,
3949
+ ...style
3950
+ };
3951
+ return /* @__PURE__ */ jsx49(
3952
+ "span",
3953
+ {
3954
+ ref,
3955
+ className,
3956
+ style: wrapperStyle,
3957
+ children: /* @__PURE__ */ jsxs31(
3958
+ "span",
3959
+ {
3960
+ "data-logo-part": "logo",
3961
+ role: "img",
3962
+ "aria-label": label,
3963
+ style: {
3964
+ display: "inline-flex",
3965
+ position: "relative",
3966
+ alignItems: "center",
3967
+ fontSize: "inherit",
3968
+ fontWeight: 700,
3969
+ lineHeight: 1,
3970
+ letterSpacing: "-.055em",
3971
+ whiteSpace: "nowrap",
3972
+ userSelect: "none"
3973
+ },
3974
+ children: [
3975
+ /* @__PURE__ */ jsxs31(
3976
+ "span",
3977
+ {
3978
+ "data-logo-part": "mark",
3979
+ "aria-hidden": "true",
3980
+ style: {
3981
+ position: "relative",
3982
+ flex: "none",
3983
+ color: ringColor ?? oneColor,
3984
+ width: ".8em",
3985
+ height: ".8em",
3986
+ marginRight: tail ? ".04em" : 0
3987
+ },
3988
+ children: [
3989
+ /* @__PURE__ */ jsx49(
3990
+ "span",
3991
+ {
3992
+ "data-logo-part": "ring",
3993
+ style: {
3994
+ ...absolute,
3995
+ inset: 0,
3996
+ border: ".157em solid currentColor",
3997
+ boxSizing: "border-box"
3998
+ }
3999
+ }
4000
+ ),
4001
+ /* @__PURE__ */ jsx49(
4002
+ "span",
4003
+ {
4004
+ "data-logo-part": "core",
4005
+ style: {
4006
+ ...absolute,
4007
+ inset: 0,
4008
+ background: accent,
4009
+ opacity: 0,
4010
+ zIndex: 2
4011
+ }
4012
+ }
4013
+ ),
4014
+ /* @__PURE__ */ jsx49(
4015
+ "span",
4016
+ {
4017
+ "data-logo-part": "trail",
4018
+ style: {
4019
+ position: "absolute",
4020
+ width: "1.8em",
4021
+ height: ".045em",
4022
+ left: "50%",
4023
+ top: "50%",
4024
+ marginTop: "-.0225em",
4025
+ background: `linear-gradient(90deg, ${accent}, transparent)`,
4026
+ transformOrigin: "left center",
4027
+ opacity: 0,
4028
+ pointerEvents: "none"
4029
+ }
4030
+ }
4031
+ ),
4032
+ [0, 1].map((id) => /* @__PURE__ */ jsx49(
4033
+ "span",
4034
+ {
4035
+ "data-logo-part": "echo",
4036
+ style: {
4037
+ ...centered,
4038
+ border: `.025em solid ${accent}`,
4039
+ boxSizing: "border-box",
4040
+ opacity: 0
4041
+ }
4042
+ },
4043
+ id
4044
+ )),
4045
+ Array.from({ length: 8 }, (_, id) => /* @__PURE__ */ jsx49(
4046
+ "span",
4047
+ {
4048
+ "data-logo-part": "particle",
4049
+ style: {
4050
+ ...centered,
4051
+ width: ".055em",
4052
+ height: ".055em",
4053
+ margin: "-.0275em",
4054
+ background: accent,
4055
+ opacity: 0
4056
+ }
4057
+ },
4058
+ id
4059
+ )),
4060
+ /* @__PURE__ */ jsx49(
4061
+ "span",
4062
+ {
4063
+ "data-logo-part": "bead",
4064
+ style: { ...centered, background: accent, zIndex: 3 }
4065
+ }
4066
+ )
4067
+ ]
4068
+ }
4069
+ ),
4070
+ /* @__PURE__ */ jsxs31(
4071
+ "span",
4072
+ {
4073
+ "data-logo-part": "tail",
4074
+ "aria-hidden": "true",
4075
+ style: {
4076
+ display: "inline-flex",
4077
+ alignItems: "baseline",
4078
+ whiteSpace: "pre"
4079
+ },
4080
+ children: [
4081
+ letters.map((letter, index) => /* @__PURE__ */ jsx49(
4082
+ "span",
4083
+ {
4084
+ "data-brand-letter": "",
4085
+ style: { display: "inline-block", color: index < 2 ? oneColor : productColor },
4086
+ children: letter
4087
+ },
4088
+ `${index}-${letter}`
4089
+ )),
4090
+ /* @__PURE__ */ jsx49(
4091
+ "span",
4092
+ {
4093
+ "data-brand-baseline": "",
4094
+ style: {
4095
+ display: "inline-block",
4096
+ width: 0,
4097
+ height: 0,
4098
+ alignSelf: "baseline"
4099
+ }
4100
+ }
4101
+ )
4102
+ ]
4103
+ }
4104
+ )
4105
+ ]
4106
+ }
4107
+ )
4108
+ }
4109
+ );
4110
+ }
3216
4111
  export {
3217
4112
  AiButton,
3218
4113
  AiExplainButton,
3219
4114
  AlertBox,
4115
+ AnimatedBrand,
4116
+ AsyncBoundary,
4117
+ BRAND_ANIMATIONS,
3220
4118
  Badge,
3221
4119
  Button,
3222
4120
  ButtonGroup,
@@ -3254,13 +4152,16 @@ export {
3254
4152
  DropdownMenuSubContent,
3255
4153
  DropdownMenuSubTrigger,
3256
4154
  DropdownMenuTrigger,
4155
+ ErrorState,
3257
4156
  FormField,
3258
4157
  FormModal,
4158
+ InlineError,
3259
4159
  Input,
3260
4160
  KpiCard,
3261
4161
  Label,
3262
4162
  LoadingOverlay,
3263
4163
  LoadingSpinner,
4164
+ LoadingState,
3264
4165
  Modal,
3265
4166
  NavGroup,
3266
4167
  NavItem,
@@ -3269,6 +4170,7 @@ export {
3269
4170
  PopoverContent,
3270
4171
  PopoverTrigger,
3271
4172
  QuestionDialog,
4173
+ RefreshBar,
3272
4174
  ResponsivePanel,
3273
4175
  ScrollArea,
3274
4176
  ScrollBar,
@@ -3322,11 +4224,14 @@ export {
3322
4224
  badgeVariants,
3323
4225
  buttonVariants,
3324
4226
  cn,
4227
+ defaultErrorStateLabels,
3325
4228
  describeSpeechError,
3326
4229
  getConfirmButtonPlacement,
3327
4230
  isWindowsPlatform,
3328
4231
  loadingSpinnerIconVariants,
3329
4232
  sheetVariants,
4233
+ toErrorInfo,
4234
+ useDelayedFlag,
3330
4235
  useMediaQuery,
3331
4236
  useSidebarCollapsed,
3332
4237
  useSpeechRecognition