@estiva-app/ui 0.24.1 → 0.26.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.
Files changed (47) hide show
  1. package/dist/AttachmentCard.d.ts +48 -6
  2. package/dist/AttachmentCard.d.ts.map +1 -1
  3. package/dist/ErrorBoundary.d.ts +32 -0
  4. package/dist/ErrorBoundary.d.ts.map +1 -0
  5. package/dist/Lightbox.d.ts +30 -0
  6. package/dist/Lightbox.d.ts.map +1 -0
  7. package/dist/ListColumn.d.ts +9 -8
  8. package/dist/ListColumn.d.ts.map +1 -1
  9. package/dist/Menu.d.ts +7 -0
  10. package/dist/Menu.d.ts.map +1 -1
  11. package/dist/eslint/index.js +4 -4
  12. package/dist/eslint/index.js.map +2 -2
  13. package/dist/index.d.ts +3 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +634 -456
  16. package/dist/index.js.map +4 -4
  17. package/package.json +1 -1
  18. package/registry.json +157 -20
  19. package/src/AttachmentCard.mdx +32 -8
  20. package/src/AttachmentCard.stories.tsx +54 -0
  21. package/src/AttachmentCard.test.tsx +115 -0
  22. package/src/AttachmentCard.tsx +212 -37
  23. package/src/CollapsibleSection.mdx +1 -1
  24. package/src/Divider.mdx +3 -3
  25. package/src/ErrorBoundary.mdx +66 -0
  26. package/src/ErrorBoundary.stories.tsx +64 -0
  27. package/src/ErrorBoundary.test.tsx +79 -0
  28. package/src/ErrorBoundary.tsx +54 -0
  29. package/src/Lightbox.mdx +71 -0
  30. package/src/Lightbox.stories.tsx +72 -0
  31. package/src/Lightbox.test.tsx +65 -0
  32. package/src/Lightbox.tsx +87 -0
  33. package/src/ListColumn.mdx +11 -3
  34. package/src/ListColumn.stories.tsx +34 -10
  35. package/src/ListColumn.test.tsx +20 -7
  36. package/src/ListColumn.tsx +34 -11
  37. package/src/Menu.mdx +5 -2
  38. package/src/Menu.stories.tsx +6 -7
  39. package/src/Menu.test.tsx +19 -1
  40. package/src/Menu.tsx +11 -1
  41. package/src/SectionHeader.mdx +5 -1
  42. package/src/SectionLabel.mdx +4 -2
  43. package/src/eslint/no-rebuilt-behaviour.ts +4 -4
  44. package/src/index.ts +3 -1
  45. package/src/registry/registry.test.ts +6 -6
  46. package/tailwind-preset.js +3 -0
  47. package/tokens.css +4 -0
package/dist/index.js CHANGED
@@ -140,7 +140,7 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
140
140
  }
141
141
 
142
142
  // src/AttachmentCard.tsx
143
- import { useLayoutEffect, useRef, useState } from "react";
143
+ import { useEffect, useLayoutEffect, useRef as useRef2, useState } from "react";
144
144
  import { Button as BaseButton2 } from "@base-ui/react/button";
145
145
  import {
146
146
  IconAlertCircle,
@@ -157,7 +157,7 @@ import {
157
157
  IconJson,
158
158
  IconLoader2,
159
159
  IconMarkdown,
160
- IconX
160
+ IconX as IconX2
161
161
  } from "@tabler/icons-react";
162
162
 
163
163
  // src/Link.tsx
@@ -406,8 +406,58 @@ function IconButton({
406
406
  return button;
407
407
  }
408
408
 
409
+ // src/Lightbox.tsx
410
+ import { useRef } from "react";
411
+ import { Dialog } from "@base-ui/react/dialog";
412
+ import { IconX } from "@tabler/icons-react";
413
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
414
+ function Lightbox({ src, alt, onClose, className }) {
415
+ const popupRef = useRef(null);
416
+ return /* @__PURE__ */ jsx9(
417
+ Dialog.Root,
418
+ {
419
+ open: true,
420
+ onOpenChange: (open) => {
421
+ if (!open) onClose();
422
+ },
423
+ children: /* @__PURE__ */ jsxs5(Dialog.Portal, { children: [
424
+ /* @__PURE__ */ jsx9(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim-strong" }),
425
+ /* @__PURE__ */ jsxs5(
426
+ Dialog.Popup,
427
+ {
428
+ ref: popupRef,
429
+ initialFocus: popupRef,
430
+ "aria-label": alt,
431
+ className: "fixed inset-0 z-50 flex items-center justify-center p-8 outline-none",
432
+ onClick: onClose,
433
+ children: [
434
+ /* @__PURE__ */ jsx9(
435
+ "img",
436
+ {
437
+ src,
438
+ alt,
439
+ onClick: (e) => e.stopPropagation(),
440
+ className: cn("max-w-full max-h-full object-contain rounded-lg", className)
441
+ }
442
+ ),
443
+ /* @__PURE__ */ jsx9(
444
+ Dialog.Close,
445
+ {
446
+ "aria-label": "Close",
447
+ className: "absolute top-4 right-4 size-8 rounded-full bg-bg-elevated border border-border-strong flex items-center justify-center text-text-secondary hover:text-text-primary",
448
+ children: /* @__PURE__ */ jsx9(IconX, { size: 16, stroke: 1.5 })
449
+ }
450
+ )
451
+ ]
452
+ }
453
+ )
454
+ ] })
455
+ }
456
+ );
457
+ }
458
+
409
459
  // src/AttachmentCard.tsx
410
- import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
460
+ import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
411
461
  var ICON_BY_EXTENSION = {
412
462
  pdf: IconFileTypePdf,
413
463
  doc: IconFileTypeDocx,
@@ -441,10 +491,10 @@ var NAME_CLASSES = "text-caption font-medium text-text-primary truncate";
441
491
  var NOTE_CLASSES = "text-small tracking-wide leading-tight truncate";
442
492
  function TypeIcon({ name }) {
443
493
  const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
444
- return /* @__PURE__ */ jsx9(Icon, { size: 20, stroke: 1.5 });
494
+ return /* @__PURE__ */ jsx10(Icon, { size: 20, stroke: 1.5 });
445
495
  }
446
496
  function Truncating({ text, hint, className, wrapperClassName, placement }) {
447
- const ref = useRef(null);
497
+ const ref = useRef2(null);
448
498
  const [cut, setCut] = useState(false);
449
499
  useLayoutEffect(() => {
450
500
  const el = ref.current;
@@ -463,9 +513,54 @@ function Truncating({ text, hint, className, wrapperClassName, placement }) {
463
513
  observer.disconnect();
464
514
  };
465
515
  }, [text, cut]);
466
- const line = /* @__PURE__ */ jsx9("span", { ref, className, children: text });
516
+ const line = /* @__PURE__ */ jsx10("span", { ref, className, children: text });
467
517
  if (!hint && !cut) return line;
468
- return /* @__PURE__ */ jsx9(WithTooltip, { label: hint ?? text, placement, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
518
+ return /* @__PURE__ */ jsx10(WithTooltip, { label: hint ?? text, placement, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
519
+ }
520
+ function useRemoteImage(url, fetchImage) {
521
+ const [result, setResult] = useState({});
522
+ const fetcher = useRef2(fetchImage);
523
+ fetcher.current = fetchImage;
524
+ useEffect(() => {
525
+ if (!url || !fetcher.current) return;
526
+ let live = true;
527
+ fetcher.current(url).then(
528
+ (src) => {
529
+ if (live) setResult({ for: url, src });
530
+ },
531
+ () => {
532
+ if (live) setResult({ for: url, failed: true });
533
+ }
534
+ );
535
+ return () => {
536
+ live = false;
537
+ };
538
+ }, [url]);
539
+ const current = result.for === url;
540
+ return { src: current ? result.src : void 0, failed: current ? !!result.failed : false };
541
+ }
542
+ async function saveFile(source, name) {
543
+ if (source.startsWith("blob:") || source.startsWith("data:")) {
544
+ handToAnchor(source, name);
545
+ return;
546
+ }
547
+ try {
548
+ const res = await fetch(source);
549
+ if (!res.ok) throw new Error(String(res.status));
550
+ const objectUrl = URL.createObjectURL(await res.blob());
551
+ handToAnchor(objectUrl, name);
552
+ URL.revokeObjectURL(objectUrl);
553
+ } catch {
554
+ window.open(source, "_blank", "noopener");
555
+ }
556
+ }
557
+ function handToAnchor(url, name) {
558
+ const a = document.createElement("a");
559
+ a.href = url;
560
+ a.download = name;
561
+ document.body.appendChild(a);
562
+ a.click();
563
+ a.remove();
469
564
  }
470
565
  function AttachmentCard({
471
566
  name,
@@ -473,8 +568,13 @@ function AttachmentCard({
473
568
  contentType,
474
569
  href,
475
570
  src,
571
+ alt,
572
+ remoteSrc,
573
+ remoteFullSrc,
574
+ fetchImage,
476
575
  onOpen,
477
576
  onDownload,
577
+ download = false,
478
578
  pending = false,
479
579
  onRemove,
480
580
  state = "ready",
@@ -485,22 +585,48 @@ function AttachmentCard({
485
585
  }) {
486
586
  const image = isImage(name, contentType);
487
587
  const sizeText = size === void 0 ? "" : formatBytes(size);
588
+ const remote = useRemoteImage(src ? void 0 : remoteSrc, fetchImage);
589
+ const picture = image ? src ?? remote.src : void 0;
590
+ const fetching = !src && !!remoteSrc && !!fetchImage;
591
+ const drawnState = state !== "ready" ? state : image && fetching ? remote.failed ? "unreadable" : picture ? "ready" : "loading" : state;
592
+ const address = href ?? (!image && fetching ? remote.src : void 0);
593
+ const [opened, setOpened] = useState(false);
594
+ const full = useRemoteImage(opened ? remoteFullSrc : void 0, fetchImage);
595
+ const openable = image && !!picture && !pending;
596
+ const openPicture = onOpen ?? (openable ? () => setOpened(true) : void 0);
597
+ const viewer = opened && picture ? /* @__PURE__ */ jsx10(Lightbox, { src: full.src ?? picture, alt: alt ?? name, onClose: () => setOpened(false) }) : null;
598
+ const saveHere = download ? () => {
599
+ const source = remoteFullSrc ?? remoteSrc;
600
+ if (source && fetchImage) {
601
+ void fetchImage(source).then(
602
+ (resolved) => saveFile(resolved, name),
603
+ // Without this a refused read is an unhandled rejection in the page
604
+ // rather than a download that did not happen.
605
+ () => {
606
+ }
607
+ );
608
+ return;
609
+ }
610
+ const local = address ?? picture;
611
+ if (local) void saveFile(local, name);
612
+ } : void 0;
613
+ const saving = onDownload ?? saveHere;
488
614
  if (pending) {
489
615
  const failed = state === "failed";
490
616
  const warning = state === "warning";
491
617
  return (
492
618
  // @estiva-escape: a failed or warning file's strong hairline is AttachmentCard's own state; Card's attention hairlines are the soft ones (UIG-9, Katerina 17 September)
493
- /* @__PURE__ */ jsxs5(
619
+ /* @__PURE__ */ jsxs6(
494
620
  Card,
495
621
  {
496
622
  fill: "elevated",
497
623
  className: cn("group relative flex items-center gap-2 w-[200px] p-1.5 pr-3", failed ? "border-error-default" : warning && "border-warning-default", className),
498
624
  ...props,
499
625
  children: [
500
- /* @__PURE__ */ jsx9("div", { className: cn(TILE_CLASSES, "overflow-hidden"), children: state === "uploading" ? /* @__PURE__ */ jsx9(IconLoader2, { size: 16, stroke: 1.5, className: "animate-spin" }) : failed ? /* @__PURE__ */ jsx9(IconAlertCircle, { size: 16, stroke: 1.5, className: "text-error-default" }) : warning ? /* @__PURE__ */ jsx9(IconAlertTriangle, { size: 16, stroke: 1.5, className: "text-warning-default" }) : image && src ? /* @__PURE__ */ jsx9("img", { src, alt: name, className: "size-full object-cover" }) : /* @__PURE__ */ jsx9("span", { className: "text-menu font-semibold", children: typeLabelOf(name) }) }),
501
- /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
502
- /* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES, placement: onRemove ? "bottom" : void 0 }),
503
- /* @__PURE__ */ jsx9(
626
+ /* @__PURE__ */ jsx10("div", { className: cn(TILE_CLASSES, "overflow-hidden"), children: state === "uploading" ? /* @__PURE__ */ jsx10(IconLoader2, { size: 16, stroke: 1.5, className: "animate-spin" }) : failed ? /* @__PURE__ */ jsx10(IconAlertCircle, { size: 16, stroke: 1.5, className: "text-error-default" }) : warning ? /* @__PURE__ */ jsx10(IconAlertTriangle, { size: 16, stroke: 1.5, className: "text-warning-default" }) : image && src ? /* @__PURE__ */ jsx10("img", { src, alt: name, className: "size-full object-cover" }) : /* @__PURE__ */ jsx10("span", { className: "text-menu font-semibold", children: typeLabelOf(name) }) }),
627
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
628
+ /* @__PURE__ */ jsx10(Truncating, { text: name, className: NAME_CLASSES, placement: onRemove ? "bottom" : void 0 }),
629
+ /* @__PURE__ */ jsx10(
504
630
  Truncating,
505
631
  {
506
632
  text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
@@ -509,7 +635,7 @@ function AttachmentCard({
509
635
  }
510
636
  )
511
637
  ] }),
512
- onRemove && /* @__PURE__ */ jsx9(
638
+ onRemove && /* @__PURE__ */ jsx10(
513
639
  BaseButton2,
514
640
  {
515
641
  type: "button",
@@ -519,7 +645,7 @@ function AttachmentCard({
519
645
  event.stopPropagation();
520
646
  onRemove();
521
647
  },
522
- children: /* @__PURE__ */ jsx9(IconX, { size: 11, stroke: 1.75 })
648
+ children: /* @__PURE__ */ jsx10(IconX2, { size: 11, stroke: 1.75 })
523
649
  }
524
650
  )
525
651
  ]
@@ -527,9 +653,9 @@ function AttachmentCard({
527
653
  )
528
654
  );
529
655
  }
530
- const download = onDownload ? (
656
+ const downloadControl = saving ? (
531
657
  // @estiva-escape: Download shows when its card is pointed at or focused, AttachmentCard's own action; IconButton has no reveal on its card's hover (UIG-9, Katerina 17 September)
532
- /* @__PURE__ */ jsx9(
658
+ /* @__PURE__ */ jsx10(
533
659
  IconButton,
534
660
  {
535
661
  variant: "muted",
@@ -538,66 +664,69 @@ function AttachmentCard({
538
664
  className: "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 transition-opacity",
539
665
  onClick: (event) => {
540
666
  event.stopPropagation();
541
- onDownload();
667
+ saving();
542
668
  },
543
- children: /* @__PURE__ */ jsx9(IconDownload, { size: 16, stroke: 1.5 })
669
+ children: /* @__PURE__ */ jsx10(IconDownload, { size: 16, stroke: 1.5 })
544
670
  }
545
671
  )
546
672
  ) : null;
547
- if (state === "loading") {
673
+ if (drawnState === "loading") {
548
674
  return (
549
675
  // `role="status"`: a plain box may not carry a name (axe, aria-prohibited-attr), and a
550
676
  // status says what it is doing — loading — to a reader that cannot see the pulse.
551
677
  // @estiva-escape: the loading pulse is AttachmentCard's own state; Card has no loading state (UIG-9, Katerina 17 September)
552
- /* @__PURE__ */ jsx9(Card, { role: "status", fill: "inset", "aria-busy": "true", "aria-label": `Loading ${name}`, className: cn("w-[180px] h-28 animate-pulse", className), ...props, children: null })
678
+ /* @__PURE__ */ jsx10(Card, { role: "status", fill: "inset", "aria-busy": "true", "aria-label": `Loading ${name}`, className: cn("w-[180px] h-28 animate-pulse", className), ...props, children: null })
553
679
  );
554
680
  }
555
- if (state === "unreadable") {
681
+ if (drawnState === "unreadable") {
556
682
  return (
557
683
  // @estiva-escape: a file that could not be read is faded as well as dashed, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
558
- /* @__PURE__ */ jsxs5(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
559
- /* @__PURE__ */ jsx9("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
560
- /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
561
- /* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
562
- /* @__PURE__ */ jsx9("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? "Could not be loaded" })
684
+ /* @__PURE__ */ jsxs6(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
685
+ /* @__PURE__ */ jsx10("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx10(TypeIcon, { name }) }),
686
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
687
+ /* @__PURE__ */ jsx10(Truncating, { text: name, className: NAME_CLASSES }),
688
+ /* @__PURE__ */ jsx10("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? "Could not be loaded" })
563
689
  ] })
564
690
  ] })
565
691
  );
566
692
  }
567
- if (image && src) {
568
- const picture = /* @__PURE__ */ jsx9("img", { src, alt: name, className: "w-full h-28 object-cover" });
569
- return /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: "hairline", clip: true, className: cn("group relative flex flex-col w-[180px]", className), ...props, children: [
570
- onOpen ? /* @__PURE__ */ jsx9(
571
- BaseButton2,
572
- {
573
- type: "button",
574
- className: "block w-full",
575
- "aria-label": `Preview ${name}`,
576
- onClick: (event) => {
577
- event.stopPropagation();
578
- onOpen();
579
- },
580
- children: picture
581
- }
582
- ) : /* @__PURE__ */ jsx9("div", { className: "block w-full", children: picture }),
583
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
584
- /* @__PURE__ */ jsx9(Truncating, { text: name, className: "flex-1 text-caption text-text-primary truncate", wrapperClassName: "flex-1" }),
585
- download
586
- ] })
693
+ if (image && picture) {
694
+ const thumbnail = /* @__PURE__ */ jsx10("img", { src: picture, alt: alt ?? name, className: "w-full h-28 object-cover" });
695
+ return /* @__PURE__ */ jsxs6(Fragment, { children: [
696
+ /* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: "hairline", clip: true, className: cn("group relative flex flex-col w-[180px]", className), ...props, children: [
697
+ openPicture ? /* @__PURE__ */ jsx10(
698
+ BaseButton2,
699
+ {
700
+ type: "button",
701
+ className: "block w-full",
702
+ "aria-label": `Preview ${name}`,
703
+ onClick: (event) => {
704
+ event.stopPropagation();
705
+ openPicture();
706
+ },
707
+ children: thumbnail
708
+ }
709
+ ) : /* @__PURE__ */ jsx10("div", { className: "block w-full", children: thumbnail }),
710
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
711
+ /* @__PURE__ */ jsx10(Truncating, { text: name, className: "flex-1 text-caption text-text-primary truncate", wrapperClassName: "flex-1" }),
712
+ downloadControl
713
+ ] })
714
+ ] }),
715
+ viewer
587
716
  ] });
588
717
  }
589
- const body = /* @__PURE__ */ jsxs5(Fragment, { children: [
590
- /* @__PURE__ */ jsx9("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
591
- /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
592
- /* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
593
- /* @__PURE__ */ jsx9("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
718
+ const body = /* @__PURE__ */ jsxs6(Fragment, { children: [
719
+ /* @__PURE__ */ jsx10("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx10(TypeIcon, { name }) }),
720
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
721
+ /* @__PURE__ */ jsx10(Truncating, { text: name, className: NAME_CLASSES }),
722
+ /* @__PURE__ */ jsx10("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
594
723
  ] })
595
724
  ] });
596
725
  return (
597
726
  // @estiva-escape: a file that cannot be opened is faded, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
598
- /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: href ? "hairline" : "none", className: cn("group flex items-center gap-2 w-[240px] p-1.5 pr-1", !href && "opacity-70", className), ...props, children: [
599
- href ? /* @__PURE__ */ jsx9(Link, { href, external: true, variant: "plain", className: "flex items-center gap-2 min-w-0 flex-1", onClick: (event) => event.stopPropagation(), children: body }) : /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: body }),
600
- download
727
+ /* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: address ? "hairline" : "none", className: cn("group flex items-center gap-2 w-[240px] p-1.5 pr-1", !address && "opacity-70", className), ...props, children: [
728
+ address ? /* @__PURE__ */ jsx10(Link, { href: address, external: true, variant: "plain", className: "flex items-center gap-2 min-w-0 flex-1", onClick: (event) => event.stopPropagation(), children: body }) : /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: body }),
729
+ downloadControl
601
730
  ] })
602
731
  );
603
732
  }
@@ -605,7 +734,7 @@ function AttachmentCard({
605
734
  // src/Avatar.tsx
606
735
  import { Avatar as BaseAvatar } from "@base-ui/react/avatar";
607
736
  import { IconUserFilled } from "@tabler/icons-react";
608
- import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
737
+ import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
609
738
  var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
610
739
  var hueFor = (key) => {
611
740
  let h = 0;
@@ -619,15 +748,15 @@ var initialsFor = (name) => {
619
748
  };
620
749
  function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
621
750
  const label = name || alt;
622
- return /* @__PURE__ */ jsxs6(
751
+ return /* @__PURE__ */ jsxs7(
623
752
  BaseAvatar.Root,
624
753
  {
625
- render: /* @__PURE__ */ jsx10("div", {}),
754
+ render: /* @__PURE__ */ jsx11("div", {}),
626
755
  ...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
627
756
  className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
628
757
  style: { width: size, height: size },
629
758
  children: [
630
- src && /* @__PURE__ */ jsx10(
759
+ src && /* @__PURE__ */ jsx11(
631
760
  BaseAvatar.Image,
632
761
  {
633
762
  src,
@@ -636,10 +765,10 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
636
765
  className: "w-full h-full object-cover data-[error]:hidden"
637
766
  }
638
767
  ),
639
- label ? /* @__PURE__ */ jsx10(
768
+ label ? /* @__PURE__ */ jsx11(
640
769
  BaseAvatar.Fallback,
641
770
  {
642
- render: /* @__PURE__ */ jsx10("div", {}),
771
+ render: /* @__PURE__ */ jsx11("div", {}),
643
772
  className: "w-full h-full flex items-center justify-center font-semibold leading-none",
644
773
  style: {
645
774
  /* eslint-disable no-restricted-syntax -- @estiva-escape: the per-person palette (the note at
@@ -653,32 +782,32 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
653
782
  background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
654
783
  /* eslint-enable no-restricted-syntax */
655
784
  },
656
- children: /* @__PURE__ */ jsx10("span", { className: "[text-box:trim-both_cap_alphabetic]", children: initialsFor(label) })
785
+ children: /* @__PURE__ */ jsx11("span", { className: "[text-box:trim-both_cap_alphabetic]", children: initialsFor(label) })
657
786
  }
658
- ) : /* @__PURE__ */ jsx10(BaseAvatar.Fallback, { render: /* @__PURE__ */ jsx10("div", {}), className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx10(IconUserFilled, { size: Math.round(size * 0.5) }) })
787
+ ) : /* @__PURE__ */ jsx11(BaseAvatar.Fallback, { render: /* @__PURE__ */ jsx11("div", {}), className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx11(IconUserFilled, { size: Math.round(size * 0.5) }) })
659
788
  ]
660
789
  }
661
790
  );
662
791
  }
663
792
 
664
793
  // src/AvatarGroup.tsx
665
- import { jsx as jsx11 } from "react/jsx-runtime";
794
+ import { jsx as jsx12 } from "react/jsx-runtime";
666
795
  function AvatarGroup({ members, size = 24 }) {
667
796
  const visible = members.slice(0, 3);
668
797
  const overlap = Math.round(size / 3);
669
798
  const ring = size / 12;
670
- return /* @__PURE__ */ jsx11("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
799
+ return /* @__PURE__ */ jsx12("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
671
800
  /*
672
801
  The wrapper carries the overlap and the ring; the face carries
673
802
  neither. It must never clip — see the note at the top of the file —
674
803
  so it has the avatar's own radius and no overflow of its own.
675
804
  */
676
- /* @__PURE__ */ jsx11(
805
+ /* @__PURE__ */ jsx12(
677
806
  "span",
678
807
  {
679
808
  className: "relative flex rounded-sm",
680
809
  style: { marginRight: -overlap, boxShadow: `0 0 0 ${ring}px var(--bg-surface)` },
681
- children: /* @__PURE__ */ jsx11(Avatar, { size, name: member.name, src: member.picture, label: member.name })
810
+ children: /* @__PURE__ */ jsx12(Avatar, { size, name: member.name, src: member.picture, label: member.name })
682
811
  },
683
812
  i
684
813
  )
@@ -686,11 +815,11 @@ function AvatarGroup({ members, size = 24 }) {
686
815
  }
687
816
 
688
817
  // src/Banner.tsx
689
- import { IconX as IconX2 } from "@tabler/icons-react";
818
+ import { IconX as IconX3 } from "@tabler/icons-react";
690
819
 
691
820
  // src/Button.tsx
692
821
  import { Button as BaseButton3 } from "@base-ui/react/button";
693
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
822
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
694
823
  function Button({
695
824
  variant = "muted",
696
825
  size = "default",
@@ -704,7 +833,7 @@ function Button({
704
833
  }) {
705
834
  const hasLeadingIcon = !!leadingIcon;
706
835
  const formBusy = useFormBusy();
707
- const button = /* @__PURE__ */ jsxs7(
836
+ const button = /* @__PURE__ */ jsxs8(
708
837
  BaseButton3,
709
838
  {
710
839
  type,
@@ -751,11 +880,11 @@ function Button({
751
880
  ]
752
881
  }
753
882
  );
754
- return disabledReason ? /* @__PURE__ */ jsx12(TooltipTrigger, { label: disabledReason, children: button }) : button;
883
+ return disabledReason ? /* @__PURE__ */ jsx13(TooltipTrigger, { label: disabledReason, children: button }) : button;
755
884
  }
756
885
 
757
886
  // src/Banner.tsx
758
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
887
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
759
888
  var TONE_STYLES = {
760
889
  ok: "bg-success-muted text-success-default",
761
890
  error: "bg-error-muted text-error-default",
@@ -765,14 +894,14 @@ var TONE_STYLES = {
765
894
  function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismiss", className }) {
766
895
  const role = tone === "error" ? "alert" : "status";
767
896
  if (!onDismiss && !icon && !action) {
768
- return /* @__PURE__ */ jsx13("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
897
+ return /* @__PURE__ */ jsx14("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
769
898
  }
770
899
  const oneLine = Boolean(icon || action);
771
- return /* @__PURE__ */ jsxs8("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
772
- icon && /* @__PURE__ */ jsx13("span", { className: "flex shrink-0", children: icon }),
773
- /* @__PURE__ */ jsx13("span", { className: cn("min-w-0 flex-1", oneLine && "truncate"), children }),
774
- action && /* @__PURE__ */ jsx13(Button, { variant: "muted", size: "small", className: "shrink-0", onClick: action.onClick, children: action.label }),
775
- onDismiss && /* @__PURE__ */ jsx13(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx13(IconX2, { size: 16, stroke: 1.5 }) })
900
+ return /* @__PURE__ */ jsxs9("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
901
+ icon && /* @__PURE__ */ jsx14("span", { className: "flex shrink-0", children: icon }),
902
+ /* @__PURE__ */ jsx14("span", { className: cn("min-w-0 flex-1", oneLine && "truncate"), children }),
903
+ action && /* @__PURE__ */ jsx14(Button, { variant: "muted", size: "small", className: "shrink-0", onClick: action.onClick, children: action.label }),
904
+ onDismiss && /* @__PURE__ */ jsx14(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx14(IconX3, { size: 16, stroke: 1.5 }) })
776
905
  ] });
777
906
  }
778
907
 
@@ -780,7 +909,7 @@ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismi
780
909
  import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
781
910
  import { Field as BaseField } from "@base-ui/react/field";
782
911
  import { IconCheck } from "@tabler/icons-react";
783
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
912
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
784
913
  function squareClasses(checked, disabled, interactive, className) {
785
914
  return cn(
786
915
  "inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
@@ -797,14 +926,14 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
797
926
  const formBusy = useFormBusy();
798
927
  const disabled = ownDisabled || formBusy;
799
928
  if (!onChange) {
800
- const picture = /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx14("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx14(IconCheck, { size: 12, stroke: 3 }) }) });
929
+ const picture = /* @__PURE__ */ jsx15("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx15("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx15(IconCheck, { size: 12, stroke: 3 }) }) });
801
930
  if (label === void 0) return picture;
802
- return /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2", children: [
931
+ return /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2", children: [
803
932
  picture,
804
- /* @__PURE__ */ jsx14("span", { className: WORDS_CLASSES, children: label })
933
+ /* @__PURE__ */ jsx15("span", { className: WORDS_CLASSES, children: label })
805
934
  ] });
806
935
  }
807
- const box = /* @__PURE__ */ jsx14(
936
+ const box = /* @__PURE__ */ jsx15(
808
937
  BaseCheckbox.Root,
809
938
  {
810
939
  checked,
@@ -814,25 +943,25 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
814
943
  onCheckedChange: (next) => onChange(next),
815
944
  onClick: (e) => e.stopPropagation(),
816
945
  className: (state) => squareClasses(state.checked, state.disabled, true, className),
817
- children: /* @__PURE__ */ jsx14(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx14(IconCheck, { size: 12, stroke: 3 }) })
946
+ children: /* @__PURE__ */ jsx15(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx15(IconCheck, { size: 12, stroke: 3 }) })
818
947
  }
819
948
  );
820
949
  if (label === void 0) return box;
821
950
  if (row) {
822
- return /* @__PURE__ */ jsx14(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs9(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
951
+ return /* @__PURE__ */ jsx15(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
823
952
  leading,
824
- /* @__PURE__ */ jsx14("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
953
+ /* @__PURE__ */ jsx15("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
825
954
  box
826
955
  ] }) });
827
956
  }
828
- return /* @__PURE__ */ jsx14(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs9(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
957
+ return /* @__PURE__ */ jsx15(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
829
958
  box,
830
- /* @__PURE__ */ jsx14("span", { className: WORDS_CLASSES, children: label })
959
+ /* @__PURE__ */ jsx15("span", { className: WORDS_CLASSES, children: label })
831
960
  ] }) });
832
961
  }
833
962
 
834
963
  // src/Chip.tsx
835
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
964
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
836
965
  var typeStyles = {
837
966
  neutral: "bg-bg-inset text-text-primary",
838
967
  brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
@@ -842,8 +971,8 @@ var typeStyles = {
842
971
  error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
843
972
  };
844
973
  function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
845
- return /* @__PURE__ */ jsxs10("div", { className: cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className), children: [
846
- leadingIcon && /* @__PURE__ */ jsx15("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
974
+ return /* @__PURE__ */ jsxs11("div", { className: cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className), children: [
975
+ leadingIcon && /* @__PURE__ */ jsx16("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
847
976
  label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
848
977
  // of growing past it — Ship's project chip on an issue row
849
978
  // (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
@@ -852,8 +981,8 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
852
981
  // the screenshot diff caught every descender cut off. `clip` is the
853
982
  // one overflow that leaves the other axis visible. A chip with no cap
854
983
  // draws exactly as before.
855
- /* @__PURE__ */ jsx15("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-small signal:font-semibold signal:tracking-wide signal:tabular-nums", children: label }),
856
- trailingIcon && /* @__PURE__ */ jsx15("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
984
+ /* @__PURE__ */ jsx16("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-small signal:font-semibold signal:tracking-wide signal:tabular-nums", children: label }),
985
+ trailingIcon && /* @__PURE__ */ jsx16("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
857
986
  ] });
858
987
  }
859
988
 
@@ -861,13 +990,13 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
861
990
  import {
862
991
  createContext as createContext4,
863
992
  useContext as useContext4,
864
- useEffect,
993
+ useEffect as useEffect2,
865
994
  useLayoutEffect as useLayoutEffect3,
866
995
  useMemo as useMemo2,
867
- useRef as useRef3,
996
+ useRef as useRef4,
868
997
  useState as useState3
869
998
  } from "react";
870
- import { Dialog } from "@base-ui/react/dialog";
999
+ import { Dialog as Dialog2 } from "@base-ui/react/dialog";
871
1000
  import { Autocomplete } from "@base-ui/react/autocomplete";
872
1001
  import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
873
1002
 
@@ -875,7 +1004,7 @@ import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
875
1004
  import { useMemo, useState as useState2 } from "react";
876
1005
  import { Button as BaseButton4 } from "@base-ui/react/button";
877
1006
  import { Combobox } from "@base-ui/react/combobox";
878
- import { IconX as IconX3 } from "@tabler/icons-react";
1007
+ import { IconX as IconX4 } from "@tabler/icons-react";
879
1008
 
880
1009
  // src/Menu.tsx
881
1010
  import { createContext as createContext3, useContext as useContext3 } from "react";
@@ -885,27 +1014,27 @@ import { Menu as BaseMenu } from "@base-ui/react/menu";
885
1014
  // src/Divider.tsx
886
1015
  import { createContext as createContext2, useContext as useContext2 } from "react";
887
1016
  import { Separator } from "@base-ui/react/separator";
888
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
1017
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
889
1018
  var DividerInPanel = createContext2(false);
890
1019
  function Divider({ orientation = "horizontal", label, tone = "default", className }) {
891
1020
  const inset = useContext2(DividerInPanel) ? "mx-0" : "mx-3";
892
1021
  if (label && orientation === "horizontal") {
893
1022
  const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
894
- return /* @__PURE__ */ jsxs11(
1023
+ return /* @__PURE__ */ jsxs12(
895
1024
  Separator,
896
1025
  {
897
1026
  orientation: "horizontal",
898
1027
  "aria-label": label,
899
1028
  className: cn("flex shrink-0 items-center gap-2", inset, className),
900
1029
  children: [
901
- /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
902
- /* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
903
- /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
1030
+ /* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
1031
+ /* @__PURE__ */ jsx17("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
1032
+ /* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
904
1033
  ]
905
1034
  }
906
1035
  );
907
1036
  }
908
- return /* @__PURE__ */ jsx16(
1037
+ return /* @__PURE__ */ jsx17(
909
1038
  Separator,
910
1039
  {
911
1040
  orientation,
@@ -921,9 +1050,9 @@ function triggerDisabled(trigger) {
921
1050
  }
922
1051
 
923
1052
  // src/SectionLabel.tsx
924
- import { jsx as jsx17 } from "react/jsx-runtime";
1053
+ import { jsx as jsx18 } from "react/jsx-runtime";
925
1054
  function SectionLabel({ children, tone = "primary", className }) {
926
- return /* @__PURE__ */ jsx17(
1055
+ return /* @__PURE__ */ jsx18(
927
1056
  "span",
928
1057
  {
929
1058
  className: cn(
@@ -937,10 +1066,10 @@ function SectionLabel({ children, tone = "primary", className }) {
937
1066
  }
938
1067
 
939
1068
  // src/Menu.tsx
940
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
1069
+ import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
941
1070
  var MenuContext = createContext3(null);
942
1071
  function MenuPanel({ children, className, ...props }) {
943
- return /* @__PURE__ */ jsx18(
1072
+ return /* @__PURE__ */ jsx19(
944
1073
  "div",
945
1074
  {
946
1075
  className: cn(
@@ -970,7 +1099,7 @@ var VIEWPORT_PAD2 = 8;
970
1099
  var HOVER_OPEN_DELAY = 0;
971
1100
  var HOVER_CLOSE_DELAY = 150;
972
1101
  function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
973
- return /* @__PURE__ */ jsxs12(
1102
+ return /* @__PURE__ */ jsxs13(
974
1103
  BaseMenu.Root,
975
1104
  {
976
1105
  open,
@@ -978,7 +1107,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
978
1107
  actionsRef,
979
1108
  modal: false,
980
1109
  children: [
981
- /* @__PURE__ */ jsx18(
1110
+ /* @__PURE__ */ jsx19(
982
1111
  BaseMenu.Trigger,
983
1112
  {
984
1113
  render: trigger,
@@ -988,7 +1117,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
988
1117
  closeDelay: HOVER_CLOSE_DELAY
989
1118
  }
990
1119
  ),
991
- /* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
1120
+ /* @__PURE__ */ jsx19(BaseMenu.Portal, { children: /* @__PURE__ */ jsx19(
992
1121
  BaseMenu.Positioner,
993
1122
  {
994
1123
  side: "bottom",
@@ -996,13 +1125,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
996
1125
  sideOffset: GAP2,
997
1126
  collisionPadding: VIEWPORT_PAD2,
998
1127
  className: "z-50 data-[anchor-hidden]:hidden",
999
- children: /* @__PURE__ */ jsx18(
1128
+ children: /* @__PURE__ */ jsx19(
1000
1129
  BaseMenu.Popup,
1001
1130
  {
1002
1131
  "data-interactive": true,
1003
1132
  className: cn("min-w-[180px] outline-none p-0", className),
1004
- render: /* @__PURE__ */ jsx18(MenuPanel, {}),
1005
- children: /* @__PURE__ */ jsx18(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx18(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx18(DividerInPanel.Provider, { value: true, children }) }) })
1133
+ render: /* @__PURE__ */ jsx19(MenuPanel, {}),
1134
+ children: /* @__PURE__ */ jsx19(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx19(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx19(DividerInPanel.Provider, { value: true, children }) }) })
1006
1135
  }
1007
1136
  )
1008
1137
  }
@@ -1018,20 +1147,20 @@ function MenuSub({ label, leading, selected, children, className }) {
1018
1147
  '[@estiva-app/ui] Menu: `openOnHover` and `MenuSub` cannot be used together \u2014 leaving the submenu panel strands the menu open. Open this menu on a press instead. See Menu.mdx, "Hover-opened menus".'
1019
1148
  );
1020
1149
  }
1021
- return /* @__PURE__ */ jsxs12(BaseMenu.SubmenuRoot, { children: [
1022
- /* @__PURE__ */ jsx18(
1150
+ return /* @__PURE__ */ jsxs13(BaseMenu.SubmenuRoot, { children: [
1151
+ /* @__PURE__ */ jsx19(
1023
1152
  BaseMenu.SubmenuTrigger,
1024
1153
  {
1025
1154
  openOnHover: true,
1026
1155
  delay: 0,
1027
1156
  closeDelay: 150,
1028
1157
  nativeButton: true,
1029
- render: /* @__PURE__ */ jsx18("button", { type: "button" }),
1158
+ render: /* @__PURE__ */ jsx19("button", { type: "button" }),
1030
1159
  className: menuItemClassName({ size: "default", selected }),
1031
- children: /* @__PURE__ */ jsx18(MenuItemBody, { label, leading, submenu: true })
1160
+ children: /* @__PURE__ */ jsx19(MenuItemBody, { label, leading, submenu: true })
1032
1161
  }
1033
1162
  ),
1034
- /* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
1163
+ /* @__PURE__ */ jsx19(BaseMenu.Portal, { children: /* @__PURE__ */ jsx19(
1035
1164
  BaseMenu.Positioner,
1036
1165
  {
1037
1166
  side: "inline-end",
@@ -1039,7 +1168,7 @@ function MenuSub({ label, leading, selected, children, className }) {
1039
1168
  sideOffset: GAP2,
1040
1169
  collisionPadding: VIEWPORT_PAD2,
1041
1170
  className: "z-50 data-[anchor-hidden]:hidden",
1042
- children: /* @__PURE__ */ jsx18(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx18(MenuPanel, {}), children })
1171
+ children: /* @__PURE__ */ jsx19(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx19(MenuPanel, {}), children })
1043
1172
  }
1044
1173
  ) })
1045
1174
  ] });
@@ -1074,25 +1203,25 @@ function menuItemClassName({ size, selected, className }) {
1074
1203
  );
1075
1204
  }
1076
1205
  function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
1077
- const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx18(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx18(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
1078
- return /* @__PURE__ */ jsxs12(Fragment2, { children: [
1079
- leading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: leading }),
1080
- children ?? /* @__PURE__ */ jsxs12("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
1081
- /* @__PURE__ */ jsx18("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
1082
- description && /* @__PURE__ */ jsx18("span", { className: "truncate text-caption text-text-secondary", children: description })
1206
+ const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx19(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx19(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
1207
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
1208
+ leading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: leading }),
1209
+ children ?? /* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
1210
+ /* @__PURE__ */ jsx19("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
1211
+ description && /* @__PURE__ */ jsx19("span", { className: "truncate text-caption text-text-secondary", children: description })
1083
1212
  ] }),
1084
1213
  (edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
1085
1214
  // the wider of the two and never changes, so revealing the hint moves
1086
1215
  // nothing. No transition here either — the hint switches on the same
1087
1216
  // :hover / `selected` as the fill, in the same frame.
1088
- /* @__PURE__ */ jsxs12("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
1089
- edge && /* @__PURE__ */ jsx18("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
1090
- hint && /* @__PURE__ */ jsx18("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
1217
+ /* @__PURE__ */ jsxs13("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
1218
+ edge && /* @__PURE__ */ jsx19("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
1219
+ hint && /* @__PURE__ */ jsx19("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
1091
1220
  ] })
1092
1221
  ] });
1093
1222
  }
1094
1223
  function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
1095
- const body = /* @__PURE__ */ jsx18(
1224
+ const body = /* @__PURE__ */ jsx19(
1096
1225
  MenuItemBody,
1097
1226
  {
1098
1227
  label,
@@ -1110,13 +1239,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
1110
1239
  );
1111
1240
  const rowClassName = menuItemClassName({ size, selected, className });
1112
1241
  if (!useContext3(MenuContext)) {
1113
- return /* @__PURE__ */ jsx18("button", { type: "button", className: rowClassName, ...props, children: body });
1242
+ return /* @__PURE__ */ jsx19("button", { type: "button", className: rowClassName, ...props, children: body });
1114
1243
  }
1115
- return /* @__PURE__ */ jsx18(
1244
+ return /* @__PURE__ */ jsx19(
1116
1245
  BaseMenu.Item,
1117
1246
  {
1118
1247
  nativeButton: true,
1119
- render: /* @__PURE__ */ jsx18("button", { type: "button" }),
1248
+ render: /* @__PURE__ */ jsx19("button", { type: "button" }),
1120
1249
  className: rowClassName,
1121
1250
  ...props,
1122
1251
  children: body
@@ -1124,31 +1253,34 @@ function MenuItem({ label, children, size = "default", description, leading, tra
1124
1253
  );
1125
1254
  }
1126
1255
  function EnterHint({ target }) {
1127
- return /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
1128
- /* @__PURE__ */ jsx18(Kbd, { children: "\u21A9 Enter" }),
1129
- target && /* @__PURE__ */ jsx18("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider", children: target })
1256
+ return /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
1257
+ /* @__PURE__ */ jsx19(Kbd, { children: "\u21A9 Enter" }),
1258
+ target && /* @__PURE__ */ jsx19("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider", children: target })
1130
1259
  ] });
1131
1260
  }
1132
1261
  function MenuSection({ label, children, className }) {
1133
1262
  const inMenu = useContext3(MenuContext) !== null;
1134
- const heading = /* @__PURE__ */ jsx18("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx18(SectionLabel, { tone: "secondary", children: label }) });
1263
+ const heading = /* @__PURE__ */ jsx19("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx19(SectionLabel, { tone: "secondary", children: label }) });
1135
1264
  if (!inMenu) {
1136
- return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col", children: [
1265
+ return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col", children: [
1137
1266
  heading,
1138
1267
  children
1139
1268
  ] });
1140
1269
  }
1141
- return /* @__PURE__ */ jsxs12(BaseMenu.Group, { className: "flex flex-col", children: [
1142
- /* @__PURE__ */ jsx18(BaseMenu.GroupLabel, { render: heading }),
1270
+ return /* @__PURE__ */ jsxs13(BaseMenu.Group, { className: "flex flex-col", children: [
1271
+ /* @__PURE__ */ jsx19(BaseMenu.GroupLabel, { render: heading }),
1143
1272
  children
1144
1273
  ] });
1145
1274
  }
1275
+ function MenuSeparator() {
1276
+ return /* @__PURE__ */ jsx19(Divider, { className: "my-1" });
1277
+ }
1146
1278
  function MenuRow({ children, className }) {
1147
- return /* @__PURE__ */ jsx18("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
1279
+ return /* @__PURE__ */ jsx19("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
1148
1280
  }
1149
1281
 
1150
1282
  // src/ChipInput.tsx
1151
- import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
1283
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1152
1284
  var CHIP_BOX = (
1153
1285
  // Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
1154
1286
  // rounded-sm corners — never a forced circle — and the chip's corner
@@ -1159,10 +1291,10 @@ var CHIP_LABEL = "text-caption font-medium text-text-primary";
1159
1291
  var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
1160
1292
  var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
1161
1293
  function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
1162
- return /* @__PURE__ */ jsxs13("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
1163
- leading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: leading }),
1164
- /* @__PURE__ */ jsx19("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
1165
- onRemove && /* @__PURE__ */ jsx19(
1294
+ return /* @__PURE__ */ jsxs14("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
1295
+ leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: leading }),
1296
+ /* @__PURE__ */ jsx20("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
1297
+ onRemove && /* @__PURE__ */ jsx20(
1166
1298
  BaseButton4,
1167
1299
  {
1168
1300
  type: "button",
@@ -1172,7 +1304,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
1172
1304
  },
1173
1305
  className: cn(CHIP_REMOVE, truncate && "shrink-0"),
1174
1306
  "aria-label": removeLabel ?? `Remove ${label}`,
1175
- children: /* @__PURE__ */ jsx19(IconX3, { size: 10, stroke: 1.5 })
1307
+ children: /* @__PURE__ */ jsx20(IconX4, { size: 10, stroke: 1.5 })
1176
1308
  }
1177
1309
  )
1178
1310
  ] });
@@ -1225,7 +1357,7 @@ function ChipInput({
1225
1357
  setQuery("");
1226
1358
  }
1227
1359
  }
1228
- return /* @__PURE__ */ jsxs13(
1360
+ return /* @__PURE__ */ jsxs14(
1229
1361
  Combobox.Root,
1230
1362
  {
1231
1363
  multiple: true,
@@ -1242,13 +1374,13 @@ function ChipInput({
1242
1374
  filter,
1243
1375
  itemToStringLabel: (option) => option.label,
1244
1376
  children: [
1245
- /* @__PURE__ */ jsxs13(Combobox.Chips, { ref: setBox, className: "bg-bg-inset border border-border-default hover:border-border-strong focus-within:border-border-focus focus-within:hover:border-border-focus rounded-lg px-3 py-1.5 flex flex-wrap items-center gap-1.5 transition-colors min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring", children: [
1246
- value.map((option) => /* @__PURE__ */ jsxs13(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
1247
- chipLeading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
1248
- /* @__PURE__ */ jsx19("span", { className: CHIP_LABEL, children: option.label }),
1249
- /* @__PURE__ */ jsx19(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx19(IconX3, { size: 10, stroke: 1.5 }) })
1377
+ /* @__PURE__ */ jsxs14(Combobox.Chips, { ref: setBox, className: "bg-bg-inset border border-border-default hover:border-border-strong focus-within:border-border-focus focus-within:hover:border-border-focus rounded-lg px-3 py-1.5 flex flex-wrap items-center gap-1.5 transition-colors min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring", children: [
1378
+ value.map((option) => /* @__PURE__ */ jsxs14(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
1379
+ chipLeading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
1380
+ /* @__PURE__ */ jsx20("span", { className: CHIP_LABEL, children: option.label }),
1381
+ /* @__PURE__ */ jsx20(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx20(IconX4, { size: 10, stroke: 1.5 }) })
1250
1382
  ] }, option.id)),
1251
- /* @__PURE__ */ jsx19(
1383
+ /* @__PURE__ */ jsx20(
1252
1384
  Combobox.Input,
1253
1385
  {
1254
1386
  autoFocus,
@@ -1260,18 +1392,18 @@ function ChipInput({
1260
1392
  }
1261
1393
  )
1262
1394
  ] }),
1263
- /* @__PURE__ */ jsx19(Combobox.Portal, { children: /* @__PURE__ */ jsx19(
1395
+ /* @__PURE__ */ jsx20(Combobox.Portal, { children: /* @__PURE__ */ jsx20(
1264
1396
  Combobox.Positioner,
1265
1397
  {
1266
1398
  anchor: box,
1267
1399
  sideOffset: GAP3,
1268
1400
  collisionPadding: VIEWPORT_PAD3,
1269
1401
  className: "z-50 data-[anchor-hidden]:hidden",
1270
- children: /* @__PURE__ */ jsx19(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx19(MenuPanel, {}), children: /* @__PURE__ */ jsx19(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx19(Combobox.List, { children: (option) => /* @__PURE__ */ jsx19(
1402
+ children: /* @__PURE__ */ jsx20(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx20(MenuPanel, {}), children: /* @__PURE__ */ jsx20(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx20(Combobox.List, { children: (option) => /* @__PURE__ */ jsx20(
1271
1403
  Combobox.Item,
1272
1404
  {
1273
1405
  value: option,
1274
- render: /* @__PURE__ */ jsx19(
1406
+ render: /* @__PURE__ */ jsx20(
1275
1407
  MenuItem,
1276
1408
  {
1277
1409
  size: "tall",
@@ -1294,22 +1426,22 @@ var VIEWPORT_PAD3 = 8;
1294
1426
 
1295
1427
  // src/EmptyState.tsx
1296
1428
  import { IconMessage2 } from "@tabler/icons-react";
1297
- import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1429
+ import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
1298
1430
  function EmptyState({ icon, message, scope = "page", action, className }) {
1299
1431
  if (scope === "section") {
1300
- return /* @__PURE__ */ jsx20("p", { className: cn("text-caption text-text-muted", className), children: message });
1432
+ return /* @__PURE__ */ jsx21("p", { className: cn("text-caption text-text-muted", className), children: message });
1301
1433
  }
1302
- return /* @__PURE__ */ jsxs14("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1303
- /* @__PURE__ */ jsx20("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx20(IconMessage2, { size: 16, stroke: 1.5 }) }),
1304
- /* @__PURE__ */ jsx20("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
1305
- action && /* @__PURE__ */ jsx20(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
1434
+ return /* @__PURE__ */ jsxs15("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1435
+ /* @__PURE__ */ jsx21("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx21(IconMessage2, { size: 16, stroke: 1.5 }) }),
1436
+ /* @__PURE__ */ jsx21("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
1437
+ action && /* @__PURE__ */ jsx21(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
1306
1438
  ] });
1307
1439
  }
1308
1440
 
1309
1441
  // src/Field.tsx
1310
1442
  import { cloneElement, isValidElement } from "react";
1311
1443
  import { Field as BaseField2 } from "@base-ui/react/field";
1312
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
1444
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
1313
1445
  var LINE_STYLES = {
1314
1446
  helper: "text-caption text-text-muted",
1315
1447
  warning: "text-caption text-warning-default",
@@ -1319,26 +1451,26 @@ function Field({ label, required = false, helper, error, children }) {
1319
1451
  const control = required && isValidElement(children) ? cloneElement(children, {
1320
1452
  "aria-required": children.props["aria-required"] ?? true
1321
1453
  }) : children;
1322
- return /* @__PURE__ */ jsxs15(BaseField2.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
1323
- /* @__PURE__ */ jsxs15(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1454
+ return /* @__PURE__ */ jsxs16(BaseField2.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
1455
+ /* @__PURE__ */ jsxs16(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1324
1456
  label,
1325
- required && /* @__PURE__ */ jsx21("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1457
+ required && /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1326
1458
  ] }),
1327
- /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1.5", children: [
1459
+ /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
1328
1460
  control,
1329
- error != null ? /* @__PURE__ */ jsx21(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx21(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
1461
+ error != null ? /* @__PURE__ */ jsx22(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx22(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
1330
1462
  ] })
1331
1463
  ] });
1332
1464
  }
1333
1465
  function FieldLine({ tone = "helper", children, className }) {
1334
- return /* @__PURE__ */ jsx21("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1466
+ return /* @__PURE__ */ jsx22("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1335
1467
  }
1336
1468
 
1337
1469
  // src/Form.tsx
1338
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef2 } from "react";
1470
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
1339
1471
  import { Fieldset } from "@base-ui/react/fieldset";
1340
1472
  import { Form as BaseForm } from "@base-ui/react/form";
1341
- import { jsx as jsx22 } from "react/jsx-runtime";
1473
+ import { jsx as jsx23 } from "react/jsx-runtime";
1342
1474
  var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
1343
1475
  var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1344
1476
  function usable(element) {
@@ -1355,12 +1487,12 @@ function firstInvalid(form) {
1355
1487
  function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, children, ...props }) {
1356
1488
  const outerBusy = useFormBusy();
1357
1489
  const busy = ownBusy || outerBusy;
1358
- const form = useRef2(null);
1359
- const busyNow = useRef2(busy);
1490
+ const form = useRef3(null);
1491
+ const busyNow = useRef3(busy);
1360
1492
  busyNow.current = busy;
1361
- const sender = useRef2(null);
1362
- const holding = useRef2(false);
1363
- const lastInside = useRef2(null);
1493
+ const sender = useRef3(null);
1494
+ const holding = useRef3(false);
1495
+ const lastInside = useRef3(null);
1364
1496
  useLayoutEffect2(() => {
1365
1497
  const element = form.current;
1366
1498
  if (!element) return;
@@ -1397,7 +1529,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
1397
1529
  const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
1398
1530
  if (enterSends && oneLine) form.current?.requestSubmit();
1399
1531
  };
1400
- return /* @__PURE__ */ jsx22(
1532
+ return /* @__PURE__ */ jsx23(
1401
1533
  BaseForm,
1402
1534
  {
1403
1535
  ref: form,
@@ -1420,29 +1552,29 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
1420
1552
  if (busyNow.current) return;
1421
1553
  void onSubmit();
1422
1554
  },
1423
- children: /* @__PURE__ */ jsx22(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx22(FormBusyContext.Provider, { value: busy, children }) })
1555
+ children: /* @__PURE__ */ jsx23(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx23(FormBusyContext.Provider, { value: busy, children }) })
1424
1556
  }
1425
1557
  );
1426
1558
  }
1427
1559
 
1428
1560
  // src/Skeleton.tsx
1429
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1561
+ import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1430
1562
  function SkeletonBar({ className, style }) {
1431
- return /* @__PURE__ */ jsx23("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1563
+ return /* @__PURE__ */ jsx24("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1432
1564
  }
1433
1565
  var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
1434
1566
  function SkeletonRow({ barWidth = 130 }) {
1435
- return /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1436
- /* @__PURE__ */ jsx23(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1437
- /* @__PURE__ */ jsx23(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1567
+ return /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1568
+ /* @__PURE__ */ jsx24(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1569
+ /* @__PURE__ */ jsx24(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1438
1570
  ] });
1439
1571
  }
1440
1572
  function SkeletonList({ rows = 8, className }) {
1441
- return /* @__PURE__ */ jsx23("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx23(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1573
+ return /* @__PURE__ */ jsx24("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx24(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1442
1574
  }
1443
1575
 
1444
1576
  // src/CommandPalette.tsx
1445
- import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1577
+ import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1446
1578
  var PaletteContext = createContext4(null);
1447
1579
  function usePalette(part) {
1448
1580
  const palette = useContext4(PaletteContext);
@@ -1457,8 +1589,8 @@ function firstControl(popup) {
1457
1589
  return popup.querySelector("[data-command-palette-fields]")?.querySelector(CONTROL2) ?? null;
1458
1590
  }
1459
1591
  function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", children }) {
1460
- const popupRef = useRef3(null);
1461
- useEffect(() => {
1592
+ const popupRef = useRef4(null);
1593
+ useEffect2(() => {
1462
1594
  if (!open) return;
1463
1595
  const frame = requestAnimationFrame(() => {
1464
1596
  const popup = popupRef.current;
@@ -1468,10 +1600,10 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
1468
1600
  return () => cancelAnimationFrame(frame);
1469
1601
  });
1470
1602
  const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
1471
- return /* @__PURE__ */ jsx24(Dialog.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs17(Dialog.Portal, { children: [
1472
- /* @__PURE__ */ jsx24(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1473
- /* @__PURE__ */ jsx24(Dialog.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx24(
1474
- Dialog.Popup,
1603
+ return /* @__PURE__ */ jsx25(Dialog2.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs18(Dialog2.Portal, { children: [
1604
+ /* @__PURE__ */ jsx25(Dialog2.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1605
+ /* @__PURE__ */ jsx25(Dialog2.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx25(
1606
+ Dialog2.Popup,
1475
1607
  {
1476
1608
  ref: popupRef,
1477
1609
  "aria-label": label,
@@ -1480,13 +1612,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
1480
1612
  if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
1481
1613
  },
1482
1614
  className: "flex w-[658px] max-w-[calc(100vw-32px)] flex-col overflow-hidden rounded-lg border border-border-default bg-bg-elevated shadow-lg outline-none",
1483
- children: /* @__PURE__ */ jsx24(PaletteContext.Provider, { value: context, children })
1615
+ children: /* @__PURE__ */ jsx25(PaletteContext.Provider, { value: context, children })
1484
1616
  }
1485
1617
  ) })
1486
1618
  ] }) });
1487
1619
  }
1488
1620
  function LevelChip({ chip, onBack }) {
1489
- return /* @__PURE__ */ jsx24(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
1621
+ return /* @__PURE__ */ jsx25(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
1490
1622
  }
1491
1623
  function useBack(chip, popupRef) {
1492
1624
  return () => {
@@ -1497,10 +1629,10 @@ function useBack(chip, popupRef) {
1497
1629
  }
1498
1630
  function Footer({ keys }) {
1499
1631
  const { where } = usePalette("The footer");
1500
- return /* @__PURE__ */ jsxs17("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted", children: [
1501
- /* @__PURE__ */ jsx24("span", { className: "min-w-0 flex-1 truncate", children: where }),
1502
- keys.map(([key, word]) => /* @__PURE__ */ jsxs17("span", { className: "flex shrink-0 items-center gap-1.5", children: [
1503
- /* @__PURE__ */ jsx24(Kbd, { children: key }),
1632
+ return /* @__PURE__ */ jsxs18("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted", children: [
1633
+ /* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 truncate", children: where }),
1634
+ keys.map(([key, word]) => /* @__PURE__ */ jsxs18("span", { className: "flex shrink-0 items-center gap-1.5", children: [
1635
+ /* @__PURE__ */ jsx25(Kbd, { children: key }),
1504
1636
  " ",
1505
1637
  word
1506
1638
  ] }, key))
@@ -1514,10 +1646,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1514
1646
  const rows = items.flatMap((g) => g.items);
1515
1647
  const [litId, setLitId] = useState3();
1516
1648
  const lit = litId === void 0 ? void 0 : rows.find((r) => r.id === litId);
1517
- const inputRef = useRef3(null);
1518
- const reported = useRef3({});
1519
- const settled = useRef3(null);
1520
- const moved = useRef3(false);
1649
+ const inputRef = useRef4(null);
1650
+ const reported = useRef4({});
1651
+ const settled = useRef4(null);
1652
+ const moved = useRef4(false);
1521
1653
  useLayoutEffect3(() => {
1522
1654
  const before = settled.current;
1523
1655
  const now = reported.current;
@@ -1577,7 +1709,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1577
1709
  ...chip && query === "" ? [["Backspace", "back"]] : [],
1578
1710
  ["Esc", "close"]
1579
1711
  ];
1580
- return /* @__PURE__ */ jsxs17(
1712
+ return /* @__PURE__ */ jsxs18(
1581
1713
  Autocomplete.Root,
1582
1714
  {
1583
1715
  items,
@@ -1600,10 +1732,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1600
1732
  setLitId(id);
1601
1733
  },
1602
1734
  children: [
1603
- /* @__PURE__ */ jsxs17("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1604
- /* @__PURE__ */ jsx24(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
1605
- chip && /* @__PURE__ */ jsx24(LevelChip, { chip, onBack: back }),
1606
- /* @__PURE__ */ jsx24(
1735
+ /* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1736
+ /* @__PURE__ */ jsx25(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
1737
+ chip && /* @__PURE__ */ jsx25(LevelChip, { chip, onBack: back }),
1738
+ /* @__PURE__ */ jsx25(
1607
1739
  Autocomplete.Input,
1608
1740
  {
1609
1741
  ref: inputRef,
@@ -1615,43 +1747,43 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1615
1747
  }
1616
1748
  )
1617
1749
  ] }),
1618
- /* @__PURE__ */ jsxs17(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
1619
- children != null && /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
1620
- /* @__PURE__ */ jsx24(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs17(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
1621
- /* @__PURE__ */ jsx24(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx24(SectionLabel, { tone: "secondary", children: group.value }) }),
1622
- /* @__PURE__ */ jsx24(Autocomplete.Collection, { children: (row) => (
1750
+ /* @__PURE__ */ jsxs18(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
1751
+ children != null && /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
1752
+ /* @__PURE__ */ jsx25(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs18(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
1753
+ /* @__PURE__ */ jsx25(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx25(SectionLabel, { tone: "secondary", children: group.value }) }),
1754
+ /* @__PURE__ */ jsx25(Autocomplete.Collection, { children: (row) => (
1623
1755
  /* The menu row, as the list's own option — the way Select
1624
1756
  puts it on `Select.Item`. One row, two parts. */
1625
- /* @__PURE__ */ jsx24(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx24(
1757
+ /* @__PURE__ */ jsx25(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx25(
1626
1758
  MenuItemBody,
1627
1759
  {
1628
1760
  size: "tall",
1629
1761
  label: row.label,
1630
1762
  description: row.description,
1631
- leading: /* @__PURE__ */ jsx24(RowLeading, { row }),
1763
+ leading: /* @__PURE__ */ jsx25(RowLeading, { row }),
1632
1764
  submenu: !!row.onGoIn,
1633
- hint: row.onGoIn ? /* @__PURE__ */ jsx24(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx24(EnterHint, {})
1765
+ hint: row.onGoIn ? /* @__PURE__ */ jsx25(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx25(EnterHint, {})
1634
1766
  }
1635
1767
  ) }, row.id)
1636
1768
  ) })
1637
1769
  ] }, group.value) }),
1638
- /* @__PURE__ */ jsx24(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs17(Fragment3, { children: [
1639
- /* @__PURE__ */ jsx24(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
1640
- /* @__PURE__ */ jsx24("span", { className: "text-caption text-text-muted", children: pending })
1770
+ /* @__PURE__ */ jsx25(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs18(Fragment3, { children: [
1771
+ /* @__PURE__ */ jsx25(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
1772
+ /* @__PURE__ */ jsx25("span", { className: "text-caption text-text-muted", children: pending })
1641
1773
  ] }) }),
1642
- notes.map((note) => /* @__PURE__ */ jsx24("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx24(FieldLine, { children: note }) }, note)),
1643
- /* @__PURE__ */ jsx24(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx24(EmptyState, { scope: "section", message: empty }) })
1774
+ notes.map((note) => /* @__PURE__ */ jsx25("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx25(FieldLine, { children: note }) }, note)),
1775
+ /* @__PURE__ */ jsx25(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx25(EmptyState, { scope: "section", message: empty }) })
1644
1776
  ] }),
1645
- /* @__PURE__ */ jsx24(Footer, { keys })
1777
+ /* @__PURE__ */ jsx25(Footer, { keys })
1646
1778
  ]
1647
1779
  }
1648
1780
  );
1649
1781
  }
1650
1782
  function RowLeading({ row }) {
1651
1783
  if (row.icon != null) {
1652
- return /* @__PURE__ */ jsx24("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
1784
+ return /* @__PURE__ */ jsx25("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
1653
1785
  }
1654
- return /* @__PURE__ */ jsx24("span", { className: "flex size-8 items-center justify-center", children: row.leading });
1786
+ return /* @__PURE__ */ jsx25("span", { className: "flex size-8 items-center justify-center", children: row.leading });
1655
1787
  }
1656
1788
  var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1657
1789
  function isTextField(el) {
@@ -1661,9 +1793,9 @@ function isTextField(el) {
1661
1793
  function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, working, error, children }) {
1662
1794
  const { modKey, popupRef } = usePalette("CommandPaletteForm");
1663
1795
  const back = useBack(chip, popupRef);
1664
- const frameRef = useRef3(null);
1796
+ const frameRef = useRef4(null);
1665
1797
  const busy = !!working;
1666
- const busyRef = useRef3(busy);
1798
+ const busyRef = useRef4(busy);
1667
1799
  busyRef.current = busy;
1668
1800
  const firstInvalid2 = () => frameRef.current?.querySelector("[data-invalid]")?.querySelector(CONTROL2) ?? null;
1669
1801
  const submit = () => {
@@ -1693,56 +1825,56 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
1693
1825
  ...backNamed ? [["Backspace", "back"]] : [],
1694
1826
  ["Esc", "close"]
1695
1827
  ];
1696
- return /* @__PURE__ */ jsxs17("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
1697
- /* @__PURE__ */ jsxs17("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1698
- icon != null && /* @__PURE__ */ jsx24("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
1699
- /* @__PURE__ */ jsx24(LevelChip, { chip, onBack: back })
1828
+ return /* @__PURE__ */ jsxs18("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
1829
+ /* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1830
+ icon != null && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
1831
+ /* @__PURE__ */ jsx25(LevelChip, { chip, onBack: back })
1700
1832
  ] }),
1701
- /* @__PURE__ */ jsxs17(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, className: "flex min-h-0 flex-col", children: [
1702
- /* @__PURE__ */ jsx24(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-4", children }) }),
1703
- /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
1704
- /* @__PURE__ */ jsx24("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx24(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx24(FieldLine, { tone: "error", children: error }) : null }),
1705
- /* @__PURE__ */ jsx24(
1833
+ /* @__PURE__ */ jsxs18(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, className: "flex min-h-0 flex-col", children: [
1834
+ /* @__PURE__ */ jsx25(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-4", children }) }),
1835
+ /* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
1836
+ /* @__PURE__ */ jsx25("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx25(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx25(FieldLine, { tone: "error", children: error }) : null }),
1837
+ /* @__PURE__ */ jsx25(
1706
1838
  Button,
1707
1839
  {
1708
1840
  type: "submit",
1709
1841
  variant: "primary",
1710
1842
  disabled: busy,
1711
1843
  disabledReason: busy ? void 0 : submitWaits,
1712
- leadingIcon: busy ? /* @__PURE__ */ jsx24(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
1844
+ leadingIcon: busy ? /* @__PURE__ */ jsx25(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
1713
1845
  children: working ? working.button : submitLabel
1714
1846
  }
1715
1847
  )
1716
1848
  ] })
1717
1849
  ] }),
1718
- /* @__PURE__ */ jsx24(Footer, { keys })
1850
+ /* @__PURE__ */ jsx25(Footer, { keys })
1719
1851
  ] });
1720
1852
  }
1721
1853
  var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
1722
1854
  function CommandPaletteWorking({ children, bars = 2 }) {
1723
- return /* @__PURE__ */ jsxs17("div", { role: "status", className: "flex flex-col gap-2", children: [
1724
- /* @__PURE__ */ jsxs17("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
1725
- /* @__PURE__ */ jsx24(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
1855
+ return /* @__PURE__ */ jsxs18("div", { role: "status", className: "flex flex-col gap-2", children: [
1856
+ /* @__PURE__ */ jsxs18("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
1857
+ /* @__PURE__ */ jsx25(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
1726
1858
  children
1727
1859
  ] }),
1728
- BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx24(SkeletonBar, { className: cn("h-3", width) }, width))
1860
+ BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx25(SkeletonBar, { className: cn("h-3", width) }, width))
1729
1861
  ] });
1730
1862
  }
1731
1863
  function CommandPaletteAnswer({ children, note }) {
1732
1864
  const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
1733
- return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
1734
- paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx24("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
1735
- (part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx24("sup", { className: "ml-0.5 font-mono text-small text-accent-primary", children: part.slice(1, -1) }, j) : part
1865
+ return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
1866
+ paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
1867
+ (part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx25("sup", { className: "ml-0.5 font-mono text-small text-accent-primary", children: part.slice(1, -1) }, j) : part
1736
1868
  ) }, i)),
1737
- note && /* @__PURE__ */ jsx24(FieldLine, { children: note })
1869
+ note && /* @__PURE__ */ jsx25(FieldLine, { children: note })
1738
1870
  ] });
1739
1871
  }
1740
1872
  function CommandPaletteQuote({ children }) {
1741
- return /* @__PURE__ */ jsx24("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
1873
+ return /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
1742
1874
  }
1743
1875
 
1744
1876
  // src/InlineChip.tsx
1745
- import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1877
+ import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
1746
1878
  var INLINE_CHIP_CLASSES = "inline-flex h-[1.4em] items-center gap-1 rounded-sm px-1 mx-0.5 align-top text-body-2 font-normal select-none";
1747
1879
  var INLINE_CHIP_TONE_CLASSES = {
1748
1880
  /** A thing or a place — anything that is not a person. */
@@ -1764,30 +1896,30 @@ function inlineChipClassName(tone, className) {
1764
1896
  return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
1765
1897
  }
1766
1898
  function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
1767
- const body = /* @__PURE__ */ jsxs18(Fragment4, { children: [
1768
- icon && /* @__PURE__ */ jsx25("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
1899
+ const body = /* @__PURE__ */ jsxs19(Fragment4, { children: [
1900
+ icon && /* @__PURE__ */ jsx26("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
1769
1901
  children
1770
1902
  ] });
1771
1903
  const classes = inlineChipClassName(tone, className);
1772
1904
  if (href === void 0) {
1773
- return /* @__PURE__ */ jsx25("span", { className: classes, ...props, children: body });
1905
+ return /* @__PURE__ */ jsx26("span", { className: classes, ...props, children: body });
1774
1906
  }
1775
- return /* @__PURE__ */ jsx25("a", { href, className: classes, ...props, children: body });
1907
+ return /* @__PURE__ */ jsx26("a", { href, className: classes, ...props, children: body });
1776
1908
  }
1777
1909
 
1778
1910
  // src/IdentityMenu.tsx
1779
- import { useCallback, useRef as useRef4 } from "react";
1911
+ import { useCallback, useRef as useRef5 } from "react";
1780
1912
 
1781
1913
  // src/Person.tsx
1782
- import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
1914
+ import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
1783
1915
  function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
1784
1916
  return (
1785
1917
  // gap-2: the face-to-name distance is one rule (8px) wherever a person
1786
1918
  // appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
1787
1919
  // row agree by construction.
1788
- /* @__PURE__ */ jsxs19("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
1789
- /* @__PURE__ */ jsx26(Avatar, { name, src: picture, size }),
1790
- /* @__PURE__ */ jsx26("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
1920
+ /* @__PURE__ */ jsxs20("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
1921
+ /* @__PURE__ */ jsx27(Avatar, { name, src: picture, size }),
1922
+ /* @__PURE__ */ jsx27("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
1791
1923
  ] })
1792
1924
  );
1793
1925
  }
@@ -1795,10 +1927,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
1795
1927
  // src/PersonTrigger.tsx
1796
1928
  import { Button as BaseButton5 } from "@base-ui/react/button";
1797
1929
  import { IconChevronDown } from "@tabler/icons-react";
1798
- import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
1930
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1799
1931
  function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
1800
1932
  if (compact) {
1801
- return /* @__PURE__ */ jsx27(
1933
+ return /* @__PURE__ */ jsx28(
1802
1934
  BaseButton5,
1803
1935
  {
1804
1936
  type: "button",
@@ -1807,11 +1939,11 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
1807
1939
  "aria-label": props["aria-label"] ?? name ?? fallback,
1808
1940
  className: cn("cursor-pointer rounded-full", className),
1809
1941
  ...props,
1810
- children: /* @__PURE__ */ jsx27(Avatar, { name, src: picture, size: size ?? 36 })
1942
+ children: /* @__PURE__ */ jsx28(Avatar, { name, src: picture, size: size ?? 36 })
1811
1943
  }
1812
1944
  );
1813
1945
  }
1814
- return /* @__PURE__ */ jsxs20(
1946
+ return /* @__PURE__ */ jsxs21(
1815
1947
  BaseButton5,
1816
1948
  {
1817
1949
  type: "button",
@@ -1829,18 +1961,18 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
1829
1961
  ),
1830
1962
  ...props,
1831
1963
  children: [
1832
- /* @__PURE__ */ jsx27(Person, { name, picture, fallback, size: size ?? 22 }),
1833
- /* @__PURE__ */ jsx27(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
1964
+ /* @__PURE__ */ jsx28(Person, { name, picture, fallback, size: size ?? 22 }),
1965
+ /* @__PURE__ */ jsx28(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
1834
1966
  ]
1835
1967
  }
1836
1968
  );
1837
1969
  }
1838
1970
 
1839
1971
  // src/IdentityMenu.tsx
1840
- import { Fragment as Fragment5, jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1972
+ import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
1841
1973
  function IdentityPanel({ className, onClose = () => {
1842
1974
  }, ...rest }) {
1843
- return /* @__PURE__ */ jsx28(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx28(IdentityRows, { ...rest, onClose }) });
1975
+ return /* @__PURE__ */ jsx29(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx29(IdentityRows, { ...rest, onClose }) });
1844
1976
  }
1845
1977
  function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
1846
1978
  const act = (action) => () => {
@@ -1848,53 +1980,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
1848
1980
  action();
1849
1981
  };
1850
1982
  const appRows = typeof children === "function" ? children(onClose) : children;
1851
- return /* @__PURE__ */ jsxs21(Fragment5, { children: [
1852
- /* @__PURE__ */ jsxs21(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
1853
- /* @__PURE__ */ jsx28(MenuRow, { children: /* @__PURE__ */ jsx28("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx28(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
1854
- /* @__PURE__ */ jsx28(Note, { children: signedIn ? "Your Estiva ID. The same person you are in every Estiva app." : "A key held by this browser only. Nobody else knows who you are." }),
1855
- me.email && /* @__PURE__ */ jsxs21(Note, { children: [
1983
+ return /* @__PURE__ */ jsxs22(Fragment5, { children: [
1984
+ /* @__PURE__ */ jsxs22(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
1985
+ /* @__PURE__ */ jsx29(MenuRow, { children: /* @__PURE__ */ jsx29("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx29(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
1986
+ /* @__PURE__ */ jsx29(Note, { children: signedIn ? "Your Estiva ID. The same person you are in every Estiva app." : "A key held by this browser only. Nobody else knows who you are." }),
1987
+ me.email && /* @__PURE__ */ jsxs22(Note, { children: [
1856
1988
  me.email,
1857
1989
  " \xB7 known to Estiva, never published to the relay"
1858
1990
  ] })
1859
1991
  ] }),
1860
- relayUrl && /* @__PURE__ */ jsxs21(Fragment5, { children: [
1861
- /* @__PURE__ */ jsx28(Divider, { className: "mx-0 my-2" }),
1862
- /* @__PURE__ */ jsxs21(MenuSection, { label: "Workspace", children: [
1863
- /* @__PURE__ */ jsx28(MenuRow, { children: /* @__PURE__ */ jsx28("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
1864
- /* @__PURE__ */ jsx28(Note, { children: "Everyone on this relay shares this workspace, in every app." })
1992
+ relayUrl && /* @__PURE__ */ jsxs22(Fragment5, { children: [
1993
+ /* @__PURE__ */ jsx29(Divider, { className: "mx-0 my-2" }),
1994
+ /* @__PURE__ */ jsxs22(MenuSection, { label: "Workspace", children: [
1995
+ /* @__PURE__ */ jsx29(MenuRow, { children: /* @__PURE__ */ jsx29("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
1996
+ /* @__PURE__ */ jsx29(Note, { children: "Everyone on this relay shares this workspace, in every app." })
1865
1997
  ] })
1866
1998
  ] }),
1867
- appRows && /* @__PURE__ */ jsxs21(Fragment5, { children: [
1868
- /* @__PURE__ */ jsx28(Divider, { className: "mx-0 my-2" }),
1999
+ appRows && /* @__PURE__ */ jsxs22(Fragment5, { children: [
2000
+ /* @__PURE__ */ jsx29(Divider, { className: "mx-0 my-2" }),
1869
2001
  appRows
1870
2002
  ] }),
1871
- signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx28(Divider, { className: "mx-0 my-2" }) : null,
1872
- signedIn && idBase && /* @__PURE__ */ jsx28(
2003
+ signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx29(Divider, { className: "mx-0 my-2" }) : null,
2004
+ signedIn && idBase && /* @__PURE__ */ jsx29(
1873
2005
  MenuItem,
1874
2006
  {
1875
2007
  label: "Edit your profile in Estiva ID",
1876
2008
  onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
1877
2009
  }
1878
2010
  ),
1879
- onCopyKey && /* @__PURE__ */ jsx28(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
1880
- idBase && onSignOut && /* @__PURE__ */ jsx28(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2011
+ onCopyKey && /* @__PURE__ */ jsx29(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2012
+ idBase && onSignOut && /* @__PURE__ */ jsx29(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
1881
2013
  ] });
1882
2014
  }
1883
2015
  function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
1884
- const actions = useRef4(null);
2016
+ const actions = useRef5(null);
1885
2017
  const close = useCallback(() => actions.current?.close(), []);
1886
2018
  return (
1887
2019
  /* The wrapper carries the caller's `className` and nothing else. It used
1888
2020
  to be `relative`, because the panel was positioned against it; the panel
1889
2021
  hangs from the trigger and portals now, so a positioning context here
1890
2022
  would only be a lie about what this box does. */
1891
- /* @__PURE__ */ jsx28("div", { className, children: /* @__PURE__ */ jsx28(
2023
+ /* @__PURE__ */ jsx29("div", { className, children: /* @__PURE__ */ jsx29(
1892
2024
  Menu,
1893
2025
  {
1894
2026
  align: "right",
1895
2027
  actionsRef: actions,
1896
2028
  className: "w-72",
1897
- trigger: /* @__PURE__ */ jsx28(
2029
+ trigger: /* @__PURE__ */ jsx29(
1898
2030
  PersonTrigger,
1899
2031
  {
1900
2032
  name: me.name,
@@ -1905,7 +2037,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
1905
2037
  "aria-label": compact ? "Account menu" : void 0
1906
2038
  }
1907
2039
  ),
1908
- children: /* @__PURE__ */ jsx28(
2040
+ children: /* @__PURE__ */ jsx29(
1909
2041
  IdentityRows,
1910
2042
  {
1911
2043
  me,
@@ -1923,14 +2055,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
1923
2055
  );
1924
2056
  }
1925
2057
  function Note({ children }) {
1926
- return /* @__PURE__ */ jsx28("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2058
+ return /* @__PURE__ */ jsx29("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
1927
2059
  }
1928
2060
 
1929
2061
  // src/FilePicker.tsx
1930
2062
  import { forwardRef } from "react";
1931
- import { jsx as jsx29 } from "react/jsx-runtime";
2063
+ import { jsx as jsx30 } from "react/jsx-runtime";
1932
2064
  var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
1933
- return /* @__PURE__ */ jsx29(
2065
+ return /* @__PURE__ */ jsx30(
1934
2066
  "input",
1935
2067
  {
1936
2068
  ref,
@@ -1951,13 +2083,13 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
1951
2083
  // src/Select.tsx
1952
2084
  import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
1953
2085
  import { Select as BaseSelect } from "@base-ui/react/select";
1954
- import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
2086
+ import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
1955
2087
  var GAP4 = 4;
1956
2088
  var VIEWPORT_PAD4 = 8;
1957
2089
  function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
1958
2090
  const selected = options.find((o) => o.value === value);
1959
2091
  const held = Boolean(disabledReason);
1960
- const trigger = /* @__PURE__ */ jsxs22(
2092
+ const trigger = /* @__PURE__ */ jsxs23(
1961
2093
  BaseSelect.Trigger,
1962
2094
  {
1963
2095
  "aria-label": ariaLabel,
@@ -1987,20 +2119,20 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1987
2119
  className
1988
2120
  ),
1989
2121
  children: [
1990
- /* @__PURE__ */ jsxs22("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
1991
- selected?.leading && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: selected.leading }),
1992
- /* @__PURE__ */ jsx30(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
2122
+ /* @__PURE__ */ jsxs23("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
2123
+ selected?.leading && /* @__PURE__ */ jsx31("span", { className: "flex shrink-0 items-center", children: selected.leading }),
2124
+ /* @__PURE__ */ jsx31(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
1993
2125
  ] }),
1994
- /* @__PURE__ */ jsx30(
2126
+ /* @__PURE__ */ jsx31(
1995
2127
  BaseSelect.Icon,
1996
2128
  {
1997
- render: /* @__PURE__ */ jsx30(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2129
+ render: /* @__PURE__ */ jsx31(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1998
2130
  }
1999
2131
  )
2000
2132
  ]
2001
2133
  }
2002
2134
  );
2003
- return /* @__PURE__ */ jsxs22(
2135
+ return /* @__PURE__ */ jsxs23(
2004
2136
  BaseSelect.Root,
2005
2137
  {
2006
2138
  value,
@@ -2012,8 +2144,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2012
2144
  disabled: disabled && !held,
2013
2145
  modal: false,
2014
2146
  children: [
2015
- held ? /* @__PURE__ */ jsx30(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2016
- /* @__PURE__ */ jsx30(BaseSelect.Portal, { children: /* @__PURE__ */ jsx30(
2147
+ held ? /* @__PURE__ */ jsx31(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2148
+ /* @__PURE__ */ jsx31(BaseSelect.Portal, { children: /* @__PURE__ */ jsx31(
2017
2149
  BaseSelect.Positioner,
2018
2150
  {
2019
2151
  side: "bottom",
@@ -2022,25 +2154,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2022
2154
  collisionPadding: VIEWPORT_PAD4,
2023
2155
  alignItemWithTrigger: false,
2024
2156
  className: "z-50 data-[anchor-hidden]:hidden",
2025
- children: /* @__PURE__ */ jsx30(
2157
+ children: /* @__PURE__ */ jsx31(
2026
2158
  BaseSelect.Popup,
2027
2159
  {
2028
- render: /* @__PURE__ */ jsx30(MenuPanel, {}),
2160
+ render: /* @__PURE__ */ jsx31(MenuPanel, {}),
2029
2161
  className: "min-w-[var(--anchor-width)] p-0",
2030
- children: /* @__PURE__ */ jsx30(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs22(
2162
+ children: /* @__PURE__ */ jsx31(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs23(
2031
2163
  BaseSelect.Item,
2032
2164
  {
2033
2165
  value: option.value,
2034
2166
  className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
2035
2167
  children: [
2036
- /* @__PURE__ */ jsxs22("span", { className: "flex min-w-0 items-center gap-2", children: [
2037
- option.leading && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: option.leading }),
2038
- /* @__PURE__ */ jsx30(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
2168
+ /* @__PURE__ */ jsxs23("span", { className: "flex min-w-0 items-center gap-2", children: [
2169
+ option.leading && /* @__PURE__ */ jsx31("span", { className: "flex shrink-0 items-center", children: option.leading }),
2170
+ /* @__PURE__ */ jsx31(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
2039
2171
  ] }),
2040
- /* @__PURE__ */ jsx30(
2172
+ /* @__PURE__ */ jsx31(
2041
2173
  BaseSelect.ItemIndicator,
2042
2174
  {
2043
- render: /* @__PURE__ */ jsx30(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2175
+ render: /* @__PURE__ */ jsx31(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2044
2176
  }
2045
2177
  )
2046
2178
  ]
@@ -2059,9 +2191,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2059
2191
  // src/TextInput.tsx
2060
2192
  import { forwardRef as forwardRef2 } from "react";
2061
2193
  import { Input } from "@base-ui/react/input";
2062
- import { jsx as jsx31 } from "react/jsx-runtime";
2194
+ import { jsx as jsx32 } from "react/jsx-runtime";
2063
2195
  var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
2064
- return /* @__PURE__ */ jsx31(
2196
+ return /* @__PURE__ */ jsx32(
2065
2197
  Input,
2066
2198
  {
2067
2199
  ref,
@@ -2088,13 +2220,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
2088
2220
  // src/Textarea.tsx
2089
2221
  import { forwardRef as forwardRef3 } from "react";
2090
2222
  import { Field as BaseField3 } from "@base-ui/react/field";
2091
- import { jsx as jsx32 } from "react/jsx-runtime";
2223
+ import { jsx as jsx33 } from "react/jsx-runtime";
2092
2224
  var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2093
- return /* @__PURE__ */ jsx32(
2225
+ return /* @__PURE__ */ jsx33(
2094
2226
  BaseField3.Control,
2095
2227
  {
2096
2228
  ref,
2097
- render: /* @__PURE__ */ jsx32("textarea", {}),
2229
+ render: /* @__PURE__ */ jsx33("textarea", {}),
2098
2230
  className: cn(
2099
2231
  // The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
2100
2232
  // "aren't there hover states in text input and text area?"). Focus comes after hover in
@@ -2115,24 +2247,24 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2115
2247
  import { useState as useState4 } from "react";
2116
2248
 
2117
2249
  // src/DialogShell.tsx
2118
- import { useRef as useRef5 } from "react";
2119
- import { Dialog as Dialog2 } from "@base-ui/react/dialog";
2250
+ import { useRef as useRef6 } from "react";
2251
+ import { Dialog as Dialog3 } from "@base-ui/react/dialog";
2120
2252
  import { AlertDialog } from "@base-ui/react/alert-dialog";
2121
- import { IconX as IconX4 } from "@tabler/icons-react";
2122
- import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
2253
+ import { IconX as IconX5 } from "@tabler/icons-react";
2254
+ import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
2123
2255
  function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
2124
- const Parts = alert ? AlertDialog : Dialog2;
2125
- const popupRef = useRef5(null);
2126
- return /* @__PURE__ */ jsx33(
2256
+ const Parts = alert ? AlertDialog : Dialog3;
2257
+ const popupRef = useRef6(null);
2258
+ return /* @__PURE__ */ jsx34(
2127
2259
  Parts.Root,
2128
2260
  {
2129
2261
  open: true,
2130
2262
  onOpenChange: (open) => {
2131
2263
  if (!open) onClose();
2132
2264
  },
2133
- children: /* @__PURE__ */ jsxs23(Parts.Portal, { children: [
2134
- /* @__PURE__ */ jsx33(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
2135
- /* @__PURE__ */ jsx33("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs23(
2265
+ children: /* @__PURE__ */ jsxs24(Parts.Portal, { children: [
2266
+ /* @__PURE__ */ jsx34(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
2267
+ /* @__PURE__ */ jsx34("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs24(
2136
2268
  Parts.Popup,
2137
2269
  {
2138
2270
  ref: popupRef,
@@ -2141,20 +2273,20 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
2141
2273
  className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
2142
2274
  style: { width },
2143
2275
  children: [
2144
- /* @__PURE__ */ jsxs23("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
2145
- headerContent ?? /* @__PURE__ */ jsx33(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx33("span", {}), children: title }),
2146
- /* @__PURE__ */ jsx33(
2276
+ /* @__PURE__ */ jsxs24("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
2277
+ headerContent ?? /* @__PURE__ */ jsx34(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx34("span", {}), children: title }),
2278
+ /* @__PURE__ */ jsx34(
2147
2279
  Parts.Close,
2148
2280
  {
2149
- render: /* @__PURE__ */ jsx33(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx33(IconX4, { size: 16, stroke: 1.5 }) })
2281
+ render: /* @__PURE__ */ jsx34(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx34(IconX5, { size: 16, stroke: 1.5 }) })
2150
2282
  }
2151
2283
  )
2152
2284
  ] }),
2153
2285
  bodyMaxHeight ? (
2154
2286
  // The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
2155
- /* @__PURE__ */ jsx33("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx33(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
2156
- ) : /* @__PURE__ */ jsx33("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
2157
- footer != null && /* @__PURE__ */ jsx33("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
2287
+ /* @__PURE__ */ jsx34("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
2288
+ ) : /* @__PURE__ */ jsx34("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
2289
+ footer != null && /* @__PURE__ */ jsx34("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
2158
2290
  ]
2159
2291
  }
2160
2292
  ) })
@@ -2164,7 +2296,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
2164
2296
  }
2165
2297
 
2166
2298
  // src/ConfirmDialog.tsx
2167
- import { Fragment as Fragment6, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
2299
+ import { Fragment as Fragment6, jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
2168
2300
  function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
2169
2301
  const [busy, setBusy] = useState4(false);
2170
2302
  const confirm = async () => {
@@ -2176,32 +2308,32 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
2176
2308
  setBusy(false);
2177
2309
  }
2178
2310
  };
2179
- return /* @__PURE__ */ jsx34(
2311
+ return /* @__PURE__ */ jsx35(
2180
2312
  DialogShell,
2181
2313
  {
2182
2314
  alert: true,
2183
2315
  title,
2184
2316
  onClose,
2185
- footer: /* @__PURE__ */ jsxs24(Fragment6, { children: [
2186
- /* @__PURE__ */ jsx34(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2187
- /* @__PURE__ */ jsx34(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2317
+ footer: /* @__PURE__ */ jsxs25(Fragment6, { children: [
2318
+ /* @__PURE__ */ jsx35(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2319
+ /* @__PURE__ */ jsx35(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2188
2320
  ] }),
2189
- children: /* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2321
+ children: /* @__PURE__ */ jsx35("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2190
2322
  }
2191
2323
  );
2192
2324
  }
2193
2325
 
2194
2326
  // src/EditableText.tsx
2195
- import { useEffect as useEffect2, useRef as useRef6, useState as useState5 } from "react";
2327
+ import { useEffect as useEffect3, useRef as useRef7, useState as useState5 } from "react";
2196
2328
  import { Field as BaseField4 } from "@base-ui/react/field";
2197
2329
  import { Input as Input2 } from "@base-ui/react/input";
2198
- import { jsx as jsx35 } from "react/jsx-runtime";
2330
+ import { jsx as jsx36 } from "react/jsx-runtime";
2199
2331
  function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
2200
2332
  const [editing, setEditing] = useState5(false);
2201
2333
  const [draft, setDraft] = useState5(value);
2202
2334
  const [busy, setBusy] = useState5(false);
2203
- const fieldRef = useRef6(null);
2204
- useEffect2(() => {
2335
+ const fieldRef = useRef7(null);
2336
+ useEffect3(() => {
2205
2337
  if (editing) {
2206
2338
  fieldRef.current?.focus();
2207
2339
  fieldRef.current?.select();
@@ -2253,7 +2385,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2253
2385
  written and never read. Read-only, this is a line of text: whatever
2254
2386
  names the region around it (a `Field`, a `Property`) names this too.
2255
2387
  */
2256
- /* @__PURE__ */ jsx35(
2388
+ /* @__PURE__ */ jsx36(
2257
2389
  "div",
2258
2390
  {
2259
2391
  className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
@@ -2263,11 +2395,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2263
2395
  );
2264
2396
  }
2265
2397
  if (editing) {
2266
- return multiline ? /* @__PURE__ */ jsx35(
2398
+ return multiline ? /* @__PURE__ */ jsx36(
2267
2399
  BaseField4.Control,
2268
2400
  {
2269
2401
  ref: fieldRef,
2270
- render: /* @__PURE__ */ jsx35("textarea", { rows: 4 }),
2402
+ render: /* @__PURE__ */ jsx36("textarea", { rows: 4 }),
2271
2403
  "aria-label": label,
2272
2404
  value: draft,
2273
2405
  disabled: busy,
@@ -2276,7 +2408,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2276
2408
  onBlur: () => void commit(),
2277
2409
  className: fieldClass
2278
2410
  }
2279
- ) : /* @__PURE__ */ jsx35(
2411
+ ) : /* @__PURE__ */ jsx36(
2280
2412
  Input2,
2281
2413
  {
2282
2414
  ref: fieldRef,
@@ -2290,7 +2422,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2290
2422
  }
2291
2423
  );
2292
2424
  }
2293
- return /* @__PURE__ */ jsx35(
2425
+ return /* @__PURE__ */ jsx36(
2294
2426
  "button",
2295
2427
  {
2296
2428
  type: "button",
@@ -2307,9 +2439,36 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2307
2439
  );
2308
2440
  }
2309
2441
 
2442
+ // src/ErrorBoundary.tsx
2443
+ import { Component } from "react";
2444
+ import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
2445
+ import { jsx as jsx37 } from "react/jsx-runtime";
2446
+ var ErrorBoundary = class extends Component {
2447
+ state = { hasError: false };
2448
+ static getDerivedStateFromError() {
2449
+ return { hasError: true };
2450
+ }
2451
+ componentDidCatch(error, info) {
2452
+ console.error(`${this.props.label ?? "part of the page"} crashed:`, error, info.componentStack ?? "");
2453
+ }
2454
+ render() {
2455
+ if (!this.state.hasError) return this.props.children;
2456
+ const message = /* @__PURE__ */ jsx37(
2457
+ EmptyState,
2458
+ {
2459
+ icon: /* @__PURE__ */ jsx37(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
2460
+ message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
2461
+ action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
2462
+ }
2463
+ );
2464
+ if (this.props.frame) return this.props.frame(message);
2465
+ return this.props.fallbackClassName ? /* @__PURE__ */ jsx37("div", { className: this.props.fallbackClassName, children: message }) : message;
2466
+ }
2467
+ };
2468
+
2310
2469
  // src/ProgressBar.tsx
2311
2470
  import { Progress } from "@base-ui/react/progress";
2312
- import { jsx as jsx36 } from "react/jsx-runtime";
2471
+ import { jsx as jsx38 } from "react/jsx-runtime";
2313
2472
  var TRACK_CLASSES = {
2314
2473
  default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
2315
2474
  // 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
@@ -2322,16 +2481,16 @@ var INDICATOR_CLASSES = {
2322
2481
  function ProgressBar({ value, max, label, variant = "default", className }) {
2323
2482
  return (
2324
2483
  // `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
2325
- /* @__PURE__ */ jsx36(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx36(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx36(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
2484
+ /* @__PURE__ */ jsx38(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx38(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx38(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
2326
2485
  );
2327
2486
  }
2328
2487
 
2329
2488
  // src/Breadcrumb.tsx
2330
- import { Fragment as Fragment7, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as useRef7, useState as useState6 } from "react";
2331
- import { jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
2489
+ import { Fragment as Fragment7, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as useRef8, useState as useState6 } from "react";
2490
+ import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
2332
2491
  function Breadcrumb({ items, className }) {
2333
- const navRef = useRef7(null);
2334
- const labelRefs = useRef7([]);
2492
+ const navRef = useRef8(null);
2493
+ const labelRefs = useRef8([]);
2335
2494
  const [truncated, setTruncated] = useState6(/* @__PURE__ */ new Set());
2336
2495
  const measure = useCallback2(() => {
2337
2496
  const next = /* @__PURE__ */ new Set();
@@ -2348,7 +2507,7 @@ function Breadcrumb({ items, className }) {
2348
2507
  observer.observe(nav);
2349
2508
  return () => observer.disconnect();
2350
2509
  }, [measure, items]);
2351
- return /* @__PURE__ */ jsx37("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-body-2", className), children: items.map((item, index) => {
2510
+ return /* @__PURE__ */ jsx39("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-body-2", className), children: items.map((item, index) => {
2352
2511
  const last = index === items.length - 1;
2353
2512
  const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
2354
2513
  const text = cn(
@@ -2369,25 +2528,25 @@ function Breadcrumb({ items, className }) {
2369
2528
  // on a box around it, which the link takes them from, rather than
2370
2529
  // pushed into it (UIG-9); the link is still the one element that
2371
2530
  // truncates and is measured.
2372
- /* @__PURE__ */ jsx37("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx37(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
2373
- ) : /* @__PURE__ */ jsx37("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
2374
- return /* @__PURE__ */ jsxs25(Fragment7, { children: [
2375
- index > 0 && /* @__PURE__ */ jsx37("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
2376
- item.icon && /* @__PURE__ */ jsx37("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
2531
+ /* @__PURE__ */ jsx39("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx39(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
2532
+ ) : /* @__PURE__ */ jsx39("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
2533
+ return /* @__PURE__ */ jsxs26(Fragment7, { children: [
2534
+ index > 0 && /* @__PURE__ */ jsx39("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
2535
+ item.icon && /* @__PURE__ */ jsx39("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
2377
2536
  truncated.has(index) ? (
2378
2537
  // `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
2379
2538
  // must keep truncating inside it, or wrapping it would widen the
2380
2539
  // trail and the tooltip would never be needed again.
2381
- /* @__PURE__ */ jsx37(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
2540
+ /* @__PURE__ */ jsx39(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
2382
2541
  ) : crumb
2383
2542
  ] }, `${item.label}-${index}`);
2384
2543
  }) });
2385
2544
  }
2386
2545
 
2387
2546
  // src/NavItem.tsx
2388
- import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
2547
+ import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
2389
2548
  function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
2390
- return /* @__PURE__ */ jsxs26(
2549
+ return /* @__PURE__ */ jsxs27(
2391
2550
  "a",
2392
2551
  {
2393
2552
  href,
@@ -2402,9 +2561,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
2402
2561
  ),
2403
2562
  ...props,
2404
2563
  children: [
2405
- icon && /* @__PURE__ */ jsx38("span", { className: "flex shrink-0 items-center", children: icon }),
2406
- /* @__PURE__ */ jsx38("span", { className: "flex-1 truncate", children: label }),
2407
- count ? /* @__PURE__ */ jsx38(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx38("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
2564
+ icon && /* @__PURE__ */ jsx40("span", { className: "flex shrink-0 items-center", children: icon }),
2565
+ /* @__PURE__ */ jsx40("span", { className: "flex-1 truncate", children: label }),
2566
+ count ? /* @__PURE__ */ jsx40(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx40("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
2408
2567
  ]
2409
2568
  }
2410
2569
  );
@@ -2413,7 +2572,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
2413
2572
  // src/Popover.tsx
2414
2573
  import { useMemo as useMemo3 } from "react";
2415
2574
  import { Popover as BasePopover } from "@base-ui/react/popover";
2416
- import { jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
2575
+ import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
2417
2576
  var GAP5 = 4;
2418
2577
  var VIEWPORT_PAD5 = 8;
2419
2578
  function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
@@ -2422,7 +2581,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
2422
2581
  if (anchor instanceof Element) return anchor;
2423
2582
  return { getBoundingClientRect: () => anchor };
2424
2583
  }, [anchor]);
2425
- return /* @__PURE__ */ jsxs27(
2584
+ return /* @__PURE__ */ jsxs28(
2426
2585
  BasePopover.Root,
2427
2586
  {
2428
2587
  open,
@@ -2430,8 +2589,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
2430
2589
  actionsRef,
2431
2590
  modal: false,
2432
2591
  children: [
2433
- trigger && /* @__PURE__ */ jsx39(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
2434
- /* @__PURE__ */ jsx39(BasePopover.Portal, { children: /* @__PURE__ */ jsx39(
2592
+ trigger && /* @__PURE__ */ jsx41(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
2593
+ /* @__PURE__ */ jsx41(BasePopover.Portal, { children: /* @__PURE__ */ jsx41(
2435
2594
  BasePopover.Positioner,
2436
2595
  {
2437
2596
  anchor: anchorTarget,
@@ -2440,20 +2599,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
2440
2599
  sideOffset: GAP5,
2441
2600
  collisionPadding: VIEWPORT_PAD5,
2442
2601
  className: "z-50 data-[anchor-hidden]:hidden",
2443
- children: /* @__PURE__ */ jsx39(
2602
+ children: /* @__PURE__ */ jsx41(
2444
2603
  BasePopover.Popup,
2445
2604
  {
2446
2605
  "aria-label": ariaLabel,
2447
2606
  initialFocus: trigger ? void 0 : false,
2448
2607
  finalFocus,
2449
2608
  className: cn("min-w-[180px] outline-none p-0", className),
2450
- render: /* @__PURE__ */ jsx39(MenuPanel, {}),
2451
- children: /* @__PURE__ */ jsx39(
2609
+ render: /* @__PURE__ */ jsx41(MenuPanel, {}),
2610
+ children: /* @__PURE__ */ jsx41(
2452
2611
  ScrollArea,
2453
2612
  {
2454
2613
  viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
2455
2614
  contentClassName: cn("flex flex-col p-2", contentClassName),
2456
- children: /* @__PURE__ */ jsx39(DividerInPanel.Provider, { value: true, children })
2615
+ children: /* @__PURE__ */ jsx41(DividerInPanel.Provider, { value: true, children })
2457
2616
  }
2458
2617
  )
2459
2618
  }
@@ -2467,9 +2626,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
2467
2626
 
2468
2627
  // src/Toolbar.tsx
2469
2628
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
2470
- import { jsx as jsx40 } from "react/jsx-runtime";
2629
+ import { jsx as jsx42 } from "react/jsx-runtime";
2471
2630
  function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
2472
- const strip = /* @__PURE__ */ jsx40(
2631
+ const strip = /* @__PURE__ */ jsx42(
2473
2632
  BaseToolbar.Root,
2474
2633
  {
2475
2634
  "aria-label": ariaLabel,
@@ -2480,27 +2639,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
2480
2639
  }
2481
2640
  );
2482
2641
  if (!surface) return strip;
2483
- return /* @__PURE__ */ jsx40(MenuPanel, { className: "w-fit p-1", children: strip });
2642
+ return /* @__PURE__ */ jsx42(MenuPanel, { className: "w-fit p-1", children: strip });
2484
2643
  }
2485
2644
  function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
2486
- return /* @__PURE__ */ jsx40(
2645
+ return /* @__PURE__ */ jsx42(
2487
2646
  BaseToolbar.Button,
2488
2647
  {
2489
2648
  ref,
2490
2649
  disabled: disabled || !!disabledReason,
2491
2650
  focusableWhenDisabled: true,
2492
- render: /* @__PURE__ */ jsx40(IconButton, { disabled, disabledReason, ...props })
2651
+ render: /* @__PURE__ */ jsx42(IconButton, { disabled, disabledReason, ...props })
2493
2652
  }
2494
2653
  );
2495
2654
  }
2496
2655
  function ToolbarLink({ ref, href, ...props }) {
2497
- return /* @__PURE__ */ jsx40(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx40(IconButton, { href, ...props }) });
2656
+ return /* @__PURE__ */ jsx42(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx42(IconButton, { href, ...props }) });
2498
2657
  }
2499
2658
  function ToolbarInput({ size, ...props }) {
2500
- return /* @__PURE__ */ jsx40(BaseToolbar.Input, { render: /* @__PURE__ */ jsx40(TextInput, { size }), ...props });
2659
+ return /* @__PURE__ */ jsx42(BaseToolbar.Input, { render: /* @__PURE__ */ jsx42(TextInput, { size }), ...props });
2501
2660
  }
2502
2661
  function ToolbarSeparator({ className }) {
2503
- return /* @__PURE__ */ jsx40(
2662
+ return /* @__PURE__ */ jsx42(
2504
2663
  BaseToolbar.Separator,
2505
2664
  {
2506
2665
  orientation: "vertical",
@@ -2510,9 +2669,9 @@ function ToolbarSeparator({ className }) {
2510
2669
  }
2511
2670
 
2512
2671
  // src/ReactionPicker.tsx
2513
- import { jsx as jsx41 } from "react/jsx-runtime";
2672
+ import { jsx as jsx43 } from "react/jsx-runtime";
2514
2673
  function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
2515
- return /* @__PURE__ */ jsx41(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
2674
+ return /* @__PURE__ */ jsx43(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
2516
2675
  /*
2517
2676
  A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
2518
2677
  would become the toolbar's item and the button inside it would never
@@ -2522,14 +2681,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
2522
2681
  The tooltip names it for a pointer, `aria-label` for everything else,
2523
2682
  and both say the meaning rather than the glyph.
2524
2683
  */
2525
- /* @__PURE__ */ jsx41(
2684
+ /* @__PURE__ */ jsx43(
2526
2685
  ToolbarButton,
2527
2686
  {
2528
2687
  "aria-label": option.label,
2529
2688
  tooltip: option.label,
2530
2689
  onClick: () => onSelect(option.emoji),
2531
2690
  className: "size-7",
2532
- children: /* @__PURE__ */ jsx41("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
2691
+ children: /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
2533
2692
  },
2534
2693
  option.emoji
2535
2694
  )
@@ -2538,23 +2697,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
2538
2697
 
2539
2698
  // src/PreviewCard.tsx
2540
2699
  import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
2541
- import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
2700
+ import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2542
2701
  var GAP6 = 12;
2543
2702
  var VIEWPORT_PAD6 = 8;
2544
2703
  var OPEN_DELAY2 = 350;
2545
2704
  var CLOSE_DELAY = 200;
2546
2705
  function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
2547
- return /* @__PURE__ */ jsxs28(BasePreviewCard.Root, { children: [
2548
- /* @__PURE__ */ jsx42(
2706
+ return /* @__PURE__ */ jsxs29(BasePreviewCard.Root, { children: [
2707
+ /* @__PURE__ */ jsx44(
2549
2708
  BasePreviewCard.Trigger,
2550
2709
  {
2551
2710
  delay,
2552
2711
  closeDelay,
2553
- render: /* @__PURE__ */ jsx42("span", { className: cn("inline-flex", wrapperClassName) }),
2712
+ render: /* @__PURE__ */ jsx44("span", { className: cn("inline-flex", wrapperClassName) }),
2554
2713
  children
2555
2714
  }
2556
2715
  ),
2557
- /* @__PURE__ */ jsx42(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx42(
2716
+ /* @__PURE__ */ jsx44(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx44(
2558
2717
  BasePreviewCard.Positioner,
2559
2718
  {
2560
2719
  side,
@@ -2562,12 +2721,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
2562
2721
  sideOffset: GAP6,
2563
2722
  collisionPadding: VIEWPORT_PAD6,
2564
2723
  className: "z-50 data-[anchor-hidden]:hidden",
2565
- children: /* @__PURE__ */ jsx42(
2724
+ children: /* @__PURE__ */ jsx44(
2566
2725
  BasePreviewCard.Popup,
2567
2726
  {
2568
2727
  className: cn("w-[360px] p-0 outline-none", className),
2569
- render: /* @__PURE__ */ jsx42(MenuPanel, {}),
2570
- children: /* @__PURE__ */ jsx42(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
2728
+ render: /* @__PURE__ */ jsx44(MenuPanel, {}),
2729
+ children: /* @__PURE__ */ jsx44(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
2571
2730
  }
2572
2731
  )
2573
2732
  }
@@ -2576,15 +2735,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
2576
2735
  }
2577
2736
 
2578
2737
  // src/Rail.tsx
2579
- import { jsx as jsx43 } from "react/jsx-runtime";
2738
+ import { jsx as jsx45 } from "react/jsx-runtime";
2580
2739
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
2581
- return /* @__PURE__ */ jsx43("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
2740
+ return /* @__PURE__ */ jsx45("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
2582
2741
  }
2583
2742
 
2584
2743
  // src/RailItem.tsx
2585
- import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2744
+ import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
2586
2745
  function RailItem({ href, icon, label, active = false, className, ...props }) {
2587
- return /* @__PURE__ */ jsxs29(
2746
+ return /* @__PURE__ */ jsxs30(
2588
2747
  "a",
2589
2748
  {
2590
2749
  href,
@@ -2592,14 +2751,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
2592
2751
  className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
2593
2752
  ...props,
2594
2753
  children: [
2595
- /* @__PURE__ */ jsx44(
2754
+ /* @__PURE__ */ jsx46(
2596
2755
  "div",
2597
2756
  {
2598
2757
  className: cn(
2599
2758
  "flex items-center justify-center rounded-lg p-2 transition-colors",
2600
2759
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
2601
2760
  ),
2602
- children: /* @__PURE__ */ jsx44(
2761
+ children: /* @__PURE__ */ jsx46(
2603
2762
  "span",
2604
2763
  {
2605
2764
  className: cn(
@@ -2611,27 +2770,27 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
2611
2770
  )
2612
2771
  }
2613
2772
  ),
2614
- /* @__PURE__ */ jsx44("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
2773
+ /* @__PURE__ */ jsx46("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
2615
2774
  ]
2616
2775
  }
2617
2776
  );
2618
2777
  }
2619
2778
 
2620
2779
  // src/Sidebar.tsx
2621
- import { jsx as jsx45 } from "react/jsx-runtime";
2780
+ import { jsx as jsx47 } from "react/jsx-runtime";
2622
2781
  function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
2623
- return /* @__PURE__ */ jsx45(
2782
+ return /* @__PURE__ */ jsx47(
2624
2783
  "nav",
2625
2784
  {
2626
2785
  "aria-label": ariaLabel,
2627
2786
  className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
2628
- children: /* @__PURE__ */ jsx45(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
2787
+ children: /* @__PURE__ */ jsx47(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
2629
2788
  }
2630
2789
  );
2631
2790
  }
2632
2791
 
2633
2792
  // src/Property.tsx
2634
- import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
2793
+ import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
2635
2794
  var VALUE_CLASSES = "contents";
2636
2795
  function Property({ label, layout = "row", children, className }) {
2637
2796
  if (layout === "stacked") {
@@ -2639,23 +2798,23 @@ function Property({ label, layout = "row", children, className }) {
2639
2798
  // gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
2640
2799
  // Peek's topic-details sections already sit at 12px, Ship's rail was
2641
2800
  // 6px, and unifying means the bigger, calmer one.
2642
- /* @__PURE__ */ jsxs30("dl", { className: cn("flex flex-col gap-3", className), children: [
2643
- /* @__PURE__ */ jsx46("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
2644
- /* @__PURE__ */ jsx46("dd", { className: VALUE_CLASSES, children })
2801
+ /* @__PURE__ */ jsxs31("dl", { className: cn("flex flex-col gap-3", className), children: [
2802
+ /* @__PURE__ */ jsx48("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
2803
+ /* @__PURE__ */ jsx48("dd", { className: VALUE_CLASSES, children })
2645
2804
  ] })
2646
2805
  );
2647
2806
  }
2648
- return /* @__PURE__ */ jsxs30("dl", { className: cn("flex items-center gap-2", className), children: [
2649
- /* @__PURE__ */ jsx46("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
2650
- /* @__PURE__ */ jsx46("dd", { className: VALUE_CLASSES, children })
2807
+ return /* @__PURE__ */ jsxs31("dl", { className: cn("flex items-center gap-2", className), children: [
2808
+ /* @__PURE__ */ jsx48("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
2809
+ /* @__PURE__ */ jsx48("dd", { className: VALUE_CLASSES, children })
2651
2810
  ] });
2652
2811
  }
2653
2812
 
2654
2813
  // src/Reaction.tsx
2655
2814
  import { Toggle } from "@base-ui/react/toggle";
2656
- import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
2815
+ import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
2657
2816
  function Reaction({ emoji, count, pressed = false, className, ...props }) {
2658
- return /* @__PURE__ */ jsxs31(
2817
+ return /* @__PURE__ */ jsxs32(
2659
2818
  Toggle,
2660
2819
  {
2661
2820
  pressed,
@@ -2677,8 +2836,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
2677
2836
  ),
2678
2837
  ...props,
2679
2838
  children: [
2680
- /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
2681
- /* @__PURE__ */ jsx47("span", { className: "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums", children: count })
2839
+ /* @__PURE__ */ jsx49("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
2840
+ /* @__PURE__ */ jsx49("span", { className: "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums", children: count })
2682
2841
  ]
2683
2842
  }
2684
2843
  );
@@ -2687,9 +2846,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
2687
2846
  // src/SearchInput.tsx
2688
2847
  import "react";
2689
2848
  import { Input as Input3 } from "@base-ui/react/input";
2690
- import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
2849
+ import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
2691
2850
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
2692
- return /* @__PURE__ */ jsxs32(
2851
+ return /* @__PURE__ */ jsxs33(
2693
2852
  "div",
2694
2853
  {
2695
2854
  className: cn(
@@ -2701,7 +2860,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
2701
2860
  className
2702
2861
  ),
2703
2862
  children: [
2704
- /* @__PURE__ */ jsx48(
2863
+ /* @__PURE__ */ jsx50(
2705
2864
  Input3,
2706
2865
  {
2707
2866
  className: "flex-1 min-w-0 bg-transparent text-input-value text-text-primary placeholder:text-text-muted outline-none",
@@ -2709,7 +2868,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
2709
2868
  ...props
2710
2869
  }
2711
2870
  ),
2712
- shortcut && /* @__PURE__ */ jsx48(Kbd, { children: shortcut })
2871
+ shortcut && /* @__PURE__ */ jsx50(Kbd, { children: shortcut })
2713
2872
  ]
2714
2873
  }
2715
2874
  );
@@ -2718,17 +2877,17 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
2718
2877
  // src/SectionHeader.tsx
2719
2878
  import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
2720
2879
  import { useRender } from "@base-ui/react/use-render";
2721
- import { Fragment as Fragment8, jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
2880
+ import { Fragment as Fragment8, jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
2722
2881
  function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", render, className }) {
2723
2882
  const titleElement = useRender({
2724
- render: render ?? (chevron ? /* @__PURE__ */ jsx49("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx49("span", {})),
2883
+ render: render ?? (chevron ? /* @__PURE__ */ jsx51("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx51("span", {})),
2725
2884
  props: {
2726
2885
  // `text-left`: a button centres its text. `h-full` and `flex-1`: the
2727
2886
  // whole row up to the actions is the hit target, as it was when the
2728
2887
  // row itself carried the click.
2729
2888
  className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
2730
- children: /* @__PURE__ */ jsxs33(Fragment8, { children: [
2731
- chevron && /* @__PURE__ */ jsx49(
2889
+ children: /* @__PURE__ */ jsxs34(Fragment8, { children: [
2890
+ chevron && /* @__PURE__ */ jsx51(
2732
2891
  IconChevronRight2,
2733
2892
  {
2734
2893
  size: 12,
@@ -2736,11 +2895,11 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2736
2895
  className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
2737
2896
  }
2738
2897
  ),
2739
- /* @__PURE__ */ jsx49(SectionLabel, { children: title })
2898
+ /* @__PURE__ */ jsx51(SectionLabel, { children: title })
2740
2899
  ] })
2741
2900
  }
2742
2901
  });
2743
- return /* @__PURE__ */ jsxs33(
2902
+ return /* @__PURE__ */ jsxs34(
2744
2903
  "div",
2745
2904
  {
2746
2905
  className: cn(
@@ -2753,15 +2912,15 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2753
2912
  ),
2754
2913
  children: [
2755
2914
  titleElement,
2756
- trailing != null && /* @__PURE__ */ jsx49("div", { className: "flex shrink-0 items-center", children: trailing }),
2757
- actions && actions.length > 0 && /* @__PURE__ */ jsx49(
2915
+ trailing != null && /* @__PURE__ */ jsx51("div", { className: "flex shrink-0 items-center", children: trailing }),
2916
+ actions && actions.length > 0 && /* @__PURE__ */ jsx51(
2758
2917
  "div",
2759
2918
  {
2760
2919
  className: cn(
2761
2920
  "-mr-1 flex shrink-0 items-center gap-1",
2762
2921
  showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
2763
2922
  ),
2764
- children: actions.map((action) => /* @__PURE__ */ jsx49(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
2923
+ children: actions.map((action) => /* @__PURE__ */ jsx51(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
2765
2924
  }
2766
2925
  )
2767
2926
  ]
@@ -2771,22 +2930,22 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2771
2930
 
2772
2931
  // src/ContainerHeader.tsx
2773
2932
  import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
2774
- import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
2933
+ import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
2775
2934
  function ContainerHeader({ title, chevron = false, actions, className }) {
2776
2935
  const text = typeof title === "string";
2777
- return /* @__PURE__ */ jsxs34("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4 pl-5", className), children: [
2778
- /* @__PURE__ */ jsx50("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs34("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
2779
- text ? /* @__PURE__ */ jsx50("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx50("div", { className: "min-w-0 flex-1", children: title }),
2780
- chevron && /* @__PURE__ */ jsx50(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2936
+ return /* @__PURE__ */ jsxs35("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4 pl-5", className), children: [
2937
+ /* @__PURE__ */ jsx52("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs35("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
2938
+ text ? /* @__PURE__ */ jsx52("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx52("div", { className: "min-w-0 flex-1", children: title }),
2939
+ chevron && /* @__PURE__ */ jsx52(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2781
2940
  ] }) }),
2782
- actions && /* @__PURE__ */ jsx50("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx50("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
2941
+ actions && /* @__PURE__ */ jsx52("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx52("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
2783
2942
  ] });
2784
2943
  }
2785
2944
 
2786
2945
  // src/ListColumn.tsx
2787
- import { jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
2788
- function ListColumn({ title, chevron = false, actions, above, spacing = "rows", collapsed = false, children, className }) {
2789
- return /* @__PURE__ */ jsxs35(
2946
+ import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
2947
+ function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
2948
+ return /* @__PURE__ */ jsxs36(
2790
2949
  "div",
2791
2950
  {
2792
2951
  className: cn(
@@ -2797,18 +2956,34 @@ function ListColumn({ title, chevron = false, actions, above, spacing = "rows",
2797
2956
  ),
2798
2957
  "data-collapsed": collapsed || void 0,
2799
2958
  children: [
2800
- /* @__PURE__ */ jsx51(ContainerHeader, { title, chevron, actions }),
2959
+ /* @__PURE__ */ jsx53(ContainerHeader, { title, chevron, actions }),
2801
2960
  above,
2802
- /* @__PURE__ */ jsx51(ScrollArea, { className: "flex-1", contentClassName: cn("flex flex-col px-3 pt-4 pb-3", spacing === "rows" ? "gap-0.5" : "gap-1"), children })
2961
+ broken ? (
2962
+ // The message takes the room the list had and centres itself in it (Katerina, 19 September).
2963
+ /* @__PURE__ */ jsx53("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
2964
+ ) : /* @__PURE__ */ jsx53(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
2803
2965
  ]
2804
2966
  }
2805
2967
  );
2806
2968
  }
2969
+ function ListColumn(props) {
2970
+ return /* @__PURE__ */ jsx53(
2971
+ ErrorBoundary,
2972
+ {
2973
+ label: "list panel",
2974
+ frame: (message) => (
2975
+ // Only the name comes back with the message: the actions and the row above may be what threw.
2976
+ /* @__PURE__ */ jsx53(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
2977
+ ),
2978
+ children: /* @__PURE__ */ jsx53(Column, { ...props })
2979
+ }
2980
+ );
2981
+ }
2807
2982
 
2808
2983
  // src/CollapsibleSection.tsx
2809
2984
  import { useState as useState7 } from "react";
2810
2985
  import { Collapsible } from "@base-ui/react/collapsible";
2811
- import { jsx as jsx52, jsxs as jsxs36 } from "react/jsx-runtime";
2986
+ import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
2812
2987
  var OPEN = "open";
2813
2988
  var CLOSED = "closed";
2814
2989
  function readStored(key) {
@@ -2835,14 +3010,14 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
2835
3010
  writeStored(storageKey, next);
2836
3011
  onOpenChange?.(next);
2837
3012
  };
2838
- return /* @__PURE__ */ jsxs36(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
2839
- /* @__PURE__ */ jsx52(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx52(Collapsible.Trigger, {}) }),
2840
- /* @__PURE__ */ jsx52(
3013
+ return /* @__PURE__ */ jsxs37(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
3014
+ /* @__PURE__ */ jsx54(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx54(Collapsible.Trigger, {}) }),
3015
+ /* @__PURE__ */ jsx54(
2841
3016
  Collapsible.Panel,
2842
3017
  {
2843
3018
  hiddenUntilFound: true,
2844
3019
  className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
2845
- children: /* @__PURE__ */ jsx52("div", { className: cn("flex flex-col", contentClassName), children })
3020
+ children: /* @__PURE__ */ jsx54("div", { className: cn("flex flex-col", contentClassName), children })
2846
3021
  }
2847
3022
  )
2848
3023
  ] });
@@ -2850,9 +3025,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
2850
3025
 
2851
3026
  // src/Tabs.tsx
2852
3027
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
2853
- import { jsx as jsx53, jsxs as jsxs37 } from "react/jsx-runtime";
3028
+ import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
2854
3029
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
2855
- return /* @__PURE__ */ jsx53(
3030
+ return /* @__PURE__ */ jsx55(
2856
3031
  BaseTabs.Root,
2857
3032
  {
2858
3033
  value: active,
@@ -2860,14 +3035,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
2860
3035
  if (details.reason === "none") onChange(value);
2861
3036
  },
2862
3037
  className,
2863
- children: /* @__PURE__ */ jsx53(
3038
+ children: /* @__PURE__ */ jsx55(
2864
3039
  BaseTabs.List,
2865
3040
  {
2866
3041
  activateOnFocus: true,
2867
3042
  "aria-label": aria["aria-label"],
2868
3043
  "aria-labelledby": aria["aria-labelledby"],
2869
3044
  className: "flex items-center gap-2",
2870
- children: tabs.map((tab) => /* @__PURE__ */ jsxs37(
3045
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs38(
2871
3046
  BaseTabs.Tab,
2872
3047
  {
2873
3048
  value: tab.id,
@@ -2880,9 +3055,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
2880
3055
  ),
2881
3056
  children: [
2882
3057
  tab.icon,
2883
- /* @__PURE__ */ jsxs37("span", { className: "flex items-baseline", children: [
3058
+ /* @__PURE__ */ jsxs38("span", { className: "flex items-baseline", children: [
2884
3059
  tab.label,
2885
- tab.count !== void 0 ? /* @__PURE__ */ jsx53("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
3060
+ tab.count !== void 0 ? /* @__PURE__ */ jsx55("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
2886
3061
  ] })
2887
3062
  ]
2888
3063
  },
@@ -2898,7 +3073,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
2898
3073
  import { createContext as createContext5, useContext as useContext5, useMemo as useMemo4 } from "react";
2899
3074
  import { Toast as BaseToast } from "@base-ui/react/toast";
2900
3075
  import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
2901
- import { jsx as jsx54, jsxs as jsxs38 } from "react/jsx-runtime";
3076
+ import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
2902
3077
  var SURFACE_STYLES = {
2903
3078
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
2904
3079
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
@@ -2934,16 +3109,16 @@ var pillClassName = (type, hasAction, className) => cn(
2934
3109
  );
2935
3110
  function LeadingIcon({ type }) {
2936
3111
  const Icon = ICONS[type];
2937
- return /* @__PURE__ */ jsx54(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
3112
+ return /* @__PURE__ */ jsx56(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
2938
3113
  }
2939
3114
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
2940
3115
  const hasAction = !!(actionLabel && onAction);
2941
- return /* @__PURE__ */ jsxs38("div", { className: pillClassName(type, hasAction, className), children: [
2942
- /* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-2 shrink-0", children: [
2943
- leadingIcon && /* @__PURE__ */ jsx54(LeadingIcon, { type }),
2944
- /* @__PURE__ */ jsx54("span", { className: LABEL_CLASSES, children: label })
3116
+ return /* @__PURE__ */ jsxs39("div", { className: pillClassName(type, hasAction, className), children: [
3117
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-2 shrink-0", children: [
3118
+ leadingIcon && /* @__PURE__ */ jsx56(LeadingIcon, { type }),
3119
+ /* @__PURE__ */ jsx56("span", { className: LABEL_CLASSES, children: label })
2945
3120
  ] }),
2946
- hasAction && /* @__PURE__ */ jsx54(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
3121
+ hasAction && /* @__PURE__ */ jsx56(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
2947
3122
  ] });
2948
3123
  }
2949
3124
  var ToastContext = createContext5(null);
@@ -2964,9 +3139,9 @@ function ToastProvider({ children }) {
2964
3139
  }),
2965
3140
  [manager]
2966
3141
  );
2967
- return /* @__PURE__ */ jsx54(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs38(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
3142
+ return /* @__PURE__ */ jsx56(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs39(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
2968
3143
  children,
2969
- /* @__PURE__ */ jsx54(BaseToast.Portal, { children: /* @__PURE__ */ jsx54(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx54(ToastList, {}) }) })
3144
+ /* @__PURE__ */ jsx56(BaseToast.Portal, { children: /* @__PURE__ */ jsx56(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx56(ToastList, {}) }) })
2970
3145
  ] }) });
2971
3146
  }
2972
3147
  function ToastList() {
@@ -2974,25 +3149,25 @@ function ToastList() {
2974
3149
  return toasts.map((toast) => {
2975
3150
  const type = toast.type ?? "neutral";
2976
3151
  const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
2977
- return /* @__PURE__ */ jsxs38(
3152
+ return /* @__PURE__ */ jsxs39(
2978
3153
  BaseToast.Root,
2979
3154
  {
2980
3155
  toast,
2981
3156
  swipeDirection: ["left", "down"],
2982
3157
  className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
2983
3158
  children: [
2984
- /* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-2 shrink-0", children: [
2985
- leadingIcon && /* @__PURE__ */ jsx54(LeadingIcon, { type }),
2986
- /* @__PURE__ */ jsx54(BaseToast.Title, { render: /* @__PURE__ */ jsx54("span", {}), className: LABEL_CLASSES })
3159
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-2 shrink-0", children: [
3160
+ leadingIcon && /* @__PURE__ */ jsx56(LeadingIcon, { type }),
3161
+ /* @__PURE__ */ jsx56(BaseToast.Title, { render: /* @__PURE__ */ jsx56("span", {}), className: LABEL_CLASSES })
2987
3162
  ] }),
2988
- actionLabel && /* @__PURE__ */ jsx54(
3163
+ actionLabel && /* @__PURE__ */ jsx56(
2989
3164
  BaseToast.Action,
2990
3165
  {
2991
3166
  onClick: () => {
2992
3167
  onAction?.();
2993
3168
  close(toast.id);
2994
3169
  },
2995
- render: /* @__PURE__ */ jsx54(Button, { variant: "outlined", size: "small", children: actionLabel })
3170
+ render: /* @__PURE__ */ jsx56(Button, { variant: "outlined", size: "small", children: actionLabel })
2996
3171
  }
2997
3172
  )
2998
3173
  ]
@@ -3032,6 +3207,7 @@ export {
3032
3207
  EditableText,
3033
3208
  EmptyState,
3034
3209
  EnterHint,
3210
+ ErrorBoundary,
3035
3211
  Field,
3036
3212
  FieldLine,
3037
3213
  FilePicker,
@@ -3044,6 +3220,7 @@ export {
3044
3220
  InlineChip,
3045
3221
  InputChip,
3046
3222
  Kbd,
3223
+ Lightbox,
3047
3224
  Link,
3048
3225
  ListColumn,
3049
3226
  Menu,
@@ -3051,6 +3228,7 @@ export {
3051
3228
  MenuPanel,
3052
3229
  MenuRow,
3053
3230
  MenuSection,
3231
+ MenuSeparator,
3054
3232
  MenuSub,
3055
3233
  NavItem,
3056
3234
  Person,