@estiva-app/ui 0.10.1 → 0.12.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 (63) hide show
  1. package/dist/AppShell.d.ts.map +1 -1
  2. package/dist/Breadcrumb.d.ts +7 -1
  3. package/dist/Breadcrumb.d.ts.map +1 -1
  4. package/dist/Chip.d.ts.map +1 -1
  5. package/dist/CollapsibleSection.d.ts +42 -0
  6. package/dist/CollapsibleSection.d.ts.map +1 -0
  7. package/dist/Divider.d.ts +15 -1
  8. package/dist/Divider.d.ts.map +1 -1
  9. package/dist/EmptyState.d.ts +19 -5
  10. package/dist/EmptyState.d.ts.map +1 -1
  11. package/dist/Menu.d.ts.map +1 -1
  12. package/dist/NavItem.d.ts.map +1 -1
  13. package/dist/Popover.d.ts.map +1 -1
  14. package/dist/PreviewCard.d.ts.map +1 -1
  15. package/dist/Reaction.d.ts.map +1 -1
  16. package/dist/ScrollArea.d.ts +46 -0
  17. package/dist/ScrollArea.d.ts.map +1 -0
  18. package/dist/SectionHeader.d.ts +31 -10
  19. package/dist/SectionHeader.d.ts.map +1 -1
  20. package/dist/Select.d.ts.map +1 -1
  21. package/dist/Sidebar.d.ts.map +1 -1
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +375 -266
  25. package/dist/index.js.map +4 -4
  26. package/package.json +1 -1
  27. package/src/AppShell.tsx +5 -0
  28. package/src/Breadcrumb.mdx +6 -0
  29. package/src/Breadcrumb.stories.tsx +12 -0
  30. package/src/Breadcrumb.test.tsx +10 -0
  31. package/src/Breadcrumb.tsx +17 -2
  32. package/src/Chip.tsx +10 -2
  33. package/src/CollapsibleSection.mdx +72 -0
  34. package/src/CollapsibleSection.stories.tsx +38 -0
  35. package/src/CollapsibleSection.test.tsx +81 -0
  36. package/src/CollapsibleSection.tsx +92 -0
  37. package/src/Divider.mdx +9 -0
  38. package/src/Divider.stories.tsx +25 -0
  39. package/src/Divider.test.tsx +26 -0
  40. package/src/Divider.tsx +30 -1
  41. package/src/EmptyState.mdx +30 -11
  42. package/src/EmptyState.stories.tsx +7 -3
  43. package/src/EmptyState.test.tsx +39 -0
  44. package/src/EmptyState.tsx +23 -6
  45. package/src/Menu.tsx +11 -2
  46. package/src/NavItem.tsx +5 -1
  47. package/src/Popover.tsx +6 -2
  48. package/src/PreviewCard.tsx +5 -2
  49. package/src/Reaction.tsx +6 -1
  50. package/src/ScrollArea.mdx +65 -0
  51. package/src/ScrollArea.stories.tsx +104 -0
  52. package/src/ScrollArea.test.tsx +65 -0
  53. package/src/ScrollArea.tsx +94 -0
  54. package/src/SectionHeader.mdx +26 -17
  55. package/src/SectionHeader.stories.tsx +4 -35
  56. package/src/SectionHeader.test.tsx +40 -0
  57. package/src/SectionHeader.tsx +70 -39
  58. package/src/Select.tsx +8 -1
  59. package/src/Sidebar.mdx +14 -10
  60. package/src/Sidebar.stories.tsx +17 -15
  61. package/src/Sidebar.tsx +8 -5
  62. package/src/index.ts +2 -0
  63. package/stories/Choosing.mdx +2 -1
package/dist/index.js CHANGED
@@ -419,9 +419,17 @@ var typeStyles = {
419
419
  error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
420
420
  };
421
421
  function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
422
- return /* @__PURE__ */ jsxs6("div", { className: cn("inline-flex items-center justify-center gap-1.5 rounded-full max-h-[20px] min-w-[16px] px-2 py-1", typeStyles[type], className), children: [
422
+ return /* @__PURE__ */ jsxs6("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: [
423
423
  leadingIcon && /* @__PURE__ */ jsx11("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
424
- label && /* @__PURE__ */ jsx11("span", { className: "text-chip whitespace-nowrap signal:font-mono signal:text-[10px] signal:font-semibold signal:tracking-[0.02em] signal:tabular-nums", children: label }),
424
+ label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
425
+ // of growing past it — Ship's project chip on an issue row
426
+ // (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
427
+ // `truncate`, because `truncate` is `overflow: hidden` on both axes and
428
+ // the label's line box (11px under Signal) is tighter than its glyphs —
429
+ // the screenshot diff caught every descender cut off. `clip` is the
430
+ // one overflow that leaves the other axis visible. A chip with no cap
431
+ // draws exactly as before.
432
+ /* @__PURE__ */ jsx11("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tracking-[0.02em] signal:tabular-nums", children: label }),
425
433
  trailingIcon && /* @__PURE__ */ jsx11("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
426
434
  ] });
427
435
  }
@@ -459,10 +467,35 @@ function triggerDisabled(trigger) {
459
467
  return !!(props.disabled || props.disabledReason);
460
468
  }
461
469
 
470
+ // src/ScrollArea.tsx
471
+ import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
472
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
473
+ var BAR = "flex touch-none select-none rounded-full opacity-0 transition-opacity delay-300 data-[hovering]:opacity-100 data-[hovering]:delay-0 data-[scrolling]:opacity-100 data-[scrolling]:delay-0";
474
+ var THUMB = "rounded-full bg-border-strong";
475
+ function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, children }) {
476
+ const vertical = orientation !== "horizontal";
477
+ const horizontal = orientation !== "vertical";
478
+ return /* @__PURE__ */ jsxs7(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
479
+ /* @__PURE__ */ jsx12(
480
+ BaseScrollArea.Viewport,
481
+ {
482
+ className: cn(
483
+ "h-full w-full outline-none data-[has-overflow-x]:overscroll-x-contain data-[has-overflow-y]:overscroll-y-contain",
484
+ viewportClassName
485
+ ),
486
+ children: /* @__PURE__ */ jsx12(BaseScrollArea.Content, { className: contentClassName, style: horizontal ? void 0 : { minWidth: 0 }, children })
487
+ }
488
+ ),
489
+ vertical && /* @__PURE__ */ jsx12(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5"), children: /* @__PURE__ */ jsx12(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
490
+ horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5"), children: /* @__PURE__ */ jsx12(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
491
+ vertical && horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Corner, {})
492
+ ] });
493
+ }
494
+
462
495
  // src/SectionLabel.tsx
463
- import { jsx as jsx12 } from "react/jsx-runtime";
496
+ import { jsx as jsx13 } from "react/jsx-runtime";
464
497
  function SectionLabel({ children, className }) {
465
- return /* @__PURE__ */ jsx12(
498
+ return /* @__PURE__ */ jsx13(
466
499
  "span",
467
500
  {
468
501
  className: cn(
@@ -475,10 +508,10 @@ function SectionLabel({ children, className }) {
475
508
  }
476
509
 
477
510
  // src/Menu.tsx
478
- import { Fragment, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
511
+ import { Fragment, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
479
512
  var MenuContext = createContext(null);
480
513
  function MenuPanel({ children, className, ...props }) {
481
- return /* @__PURE__ */ jsx13(
514
+ return /* @__PURE__ */ jsx14(
482
515
  "div",
483
516
  {
484
517
  className: cn(
@@ -508,7 +541,7 @@ var VIEWPORT_PAD2 = 8;
508
541
  var HOVER_OPEN_DELAY = 0;
509
542
  var HOVER_CLOSE_DELAY = 150;
510
543
  function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className }) {
511
- return /* @__PURE__ */ jsxs7(
544
+ return /* @__PURE__ */ jsxs8(
512
545
  BaseMenu.Root,
513
546
  {
514
547
  open,
@@ -516,7 +549,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
516
549
  actionsRef,
517
550
  modal: false,
518
551
  children: [
519
- /* @__PURE__ */ jsx13(
552
+ /* @__PURE__ */ jsx14(
520
553
  BaseMenu.Trigger,
521
554
  {
522
555
  render: trigger,
@@ -526,7 +559,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
526
559
  closeDelay: HOVER_CLOSE_DELAY
527
560
  }
528
561
  ),
529
- /* @__PURE__ */ jsx13(BaseMenu.Portal, { children: /* @__PURE__ */ jsx13(
562
+ /* @__PURE__ */ jsx14(BaseMenu.Portal, { children: /* @__PURE__ */ jsx14(
530
563
  BaseMenu.Positioner,
531
564
  {
532
565
  side: "bottom",
@@ -534,13 +567,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
534
567
  sideOffset: GAP3,
535
568
  collisionPadding: VIEWPORT_PAD2,
536
569
  className: "z-50 data-[anchor-hidden]:hidden",
537
- children: /* @__PURE__ */ jsx13(
570
+ children: /* @__PURE__ */ jsx14(
538
571
  BaseMenu.Popup,
539
572
  {
540
573
  "data-interactive": true,
541
- className: cn("min-w-[180px] max-h-[var(--available-height)] overflow-y-auto outline-none", className),
542
- render: /* @__PURE__ */ jsx13(MenuPanel, {}),
543
- children: /* @__PURE__ */ jsx13(MenuContext.Provider, { value: { openOnHover }, children })
574
+ className: cn("min-w-[180px] outline-none", className),
575
+ render: /* @__PURE__ */ jsx14(MenuPanel, {}),
576
+ children: /* @__PURE__ */ jsx14(ScrollArea, { viewportClassName: "max-h-[calc(var(--available-height)_-_1rem)]", contentClassName: "flex flex-col [&>[role=separator]]:mx-0", children: /* @__PURE__ */ jsx14(MenuContext.Provider, { value: { openOnHover }, children }) })
544
577
  }
545
578
  )
546
579
  }
@@ -556,20 +589,20 @@ function MenuSub({ label, leading, selected, children, className }) {
556
589
  '[@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".'
557
590
  );
558
591
  }
559
- return /* @__PURE__ */ jsxs7(BaseMenu.SubmenuRoot, { children: [
560
- /* @__PURE__ */ jsx13(
592
+ return /* @__PURE__ */ jsxs8(BaseMenu.SubmenuRoot, { children: [
593
+ /* @__PURE__ */ jsx14(
561
594
  BaseMenu.SubmenuTrigger,
562
595
  {
563
596
  openOnHover: true,
564
597
  delay: 0,
565
598
  closeDelay: 150,
566
599
  nativeButton: true,
567
- render: /* @__PURE__ */ jsx13("button", { type: "button" }),
600
+ render: /* @__PURE__ */ jsx14("button", { type: "button" }),
568
601
  className: menuItemClassName({ size: "default", selected }),
569
- children: /* @__PURE__ */ jsx13(MenuItemBody, { label, leading, submenu: true })
602
+ children: /* @__PURE__ */ jsx14(MenuItemBody, { label, leading, submenu: true })
570
603
  }
571
604
  ),
572
- /* @__PURE__ */ jsx13(BaseMenu.Portal, { children: /* @__PURE__ */ jsx13(
605
+ /* @__PURE__ */ jsx14(BaseMenu.Portal, { children: /* @__PURE__ */ jsx14(
573
606
  BaseMenu.Positioner,
574
607
  {
575
608
  side: "inline-end",
@@ -577,7 +610,7 @@ function MenuSub({ label, leading, selected, children, className }) {
577
610
  sideOffset: GAP3,
578
611
  collisionPadding: VIEWPORT_PAD2,
579
612
  className: "z-50 data-[anchor-hidden]:hidden",
580
- children: /* @__PURE__ */ jsx13(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx13(MenuPanel, {}), children })
613
+ children: /* @__PURE__ */ jsx14(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx14(MenuPanel, {}), children })
581
614
  }
582
615
  ) })
583
616
  ] });
@@ -609,25 +642,25 @@ function menuItemClassName({ size, selected, className }) {
609
642
  );
610
643
  }
611
644
  function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
612
- const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx13(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx13(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
613
- return /* @__PURE__ */ jsxs7(Fragment, { children: [
614
- leading && /* @__PURE__ */ jsx13("span", { className: "flex shrink-0 items-center", children: leading }),
615
- children ?? /* @__PURE__ */ jsxs7("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
616
- /* @__PURE__ */ jsx13("span", { className: cn("truncate text-[14px] leading-[140%]", destructive ? "text-error-default" : "text-text-primary"), children: label }),
617
- description && /* @__PURE__ */ jsx13("span", { className: "truncate text-[12px] leading-[120%] text-text-secondary", children: description })
645
+ const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx14(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx14(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
646
+ return /* @__PURE__ */ jsxs8(Fragment, { children: [
647
+ leading && /* @__PURE__ */ jsx14("span", { className: "flex shrink-0 items-center", children: leading }),
648
+ children ?? /* @__PURE__ */ jsxs8("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
649
+ /* @__PURE__ */ jsx14("span", { className: cn("truncate text-[14px] leading-[140%]", destructive ? "text-error-default" : "text-text-primary"), children: label }),
650
+ description && /* @__PURE__ */ jsx14("span", { className: "truncate text-[12px] leading-[120%] text-text-secondary", children: description })
618
651
  ] }),
619
652
  (edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
620
653
  // the wider of the two and never changes, so revealing the hint moves
621
654
  // nothing. No transition here either — the hint switches on the same
622
655
  // :hover / `selected` as the fill, in the same frame.
623
- /* @__PURE__ */ jsxs7("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
624
- edge && /* @__PURE__ */ jsx13("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
625
- hint && /* @__PURE__ */ jsx13("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
656
+ /* @__PURE__ */ jsxs8("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
657
+ edge && /* @__PURE__ */ jsx14("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
658
+ hint && /* @__PURE__ */ jsx14("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
626
659
  ] })
627
660
  ] });
628
661
  }
629
662
  function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
630
- const body = /* @__PURE__ */ jsx13(
663
+ const body = /* @__PURE__ */ jsx14(
631
664
  MenuItemBody,
632
665
  {
633
666
  label,
@@ -645,13 +678,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
645
678
  );
646
679
  const rowClassName = menuItemClassName({ size, selected, className });
647
680
  if (!useContext(MenuContext)) {
648
- return /* @__PURE__ */ jsx13("button", { type: "button", className: rowClassName, ...props, children: body });
681
+ return /* @__PURE__ */ jsx14("button", { type: "button", className: rowClassName, ...props, children: body });
649
682
  }
650
- return /* @__PURE__ */ jsx13(
683
+ return /* @__PURE__ */ jsx14(
651
684
  BaseMenu.Item,
652
685
  {
653
686
  nativeButton: true,
654
- render: /* @__PURE__ */ jsx13("button", { type: "button" }),
687
+ render: /* @__PURE__ */ jsx14("button", { type: "button" }),
655
688
  className: rowClassName,
656
689
  ...props,
657
690
  children: body
@@ -659,33 +692,33 @@ function MenuItem({ label, children, size = "default", description, leading, tra
659
692
  );
660
693
  }
661
694
  function EnterHint({ target }) {
662
- return /* @__PURE__ */ jsxs7("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
663
- /* @__PURE__ */ jsx13(Kbd, { children: "\u21A9 Enter" }),
664
- target && /* @__PURE__ */ jsx13("span", { className: "text-[9px] font-medium leading-[115%] signal:font-mono signal:text-[9.5px] signal:tracking-[0.04em]", children: target })
695
+ return /* @__PURE__ */ jsxs8("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
696
+ /* @__PURE__ */ jsx14(Kbd, { children: "\u21A9 Enter" }),
697
+ target && /* @__PURE__ */ jsx14("span", { className: "text-[9px] font-medium leading-[115%] signal:font-mono signal:text-[9.5px] signal:tracking-[0.04em]", children: target })
665
698
  ] });
666
699
  }
667
700
  function MenuSection({ label, children, className }) {
668
701
  const inMenu = useContext(MenuContext) !== null;
669
- const heading = /* @__PURE__ */ jsx13("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx13(SectionLabel, { className: "text-text-secondary", children: label }) });
702
+ const heading = /* @__PURE__ */ jsx14("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx14(SectionLabel, { className: "text-text-secondary", children: label }) });
670
703
  if (!inMenu) {
671
- return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col", children: [
704
+ return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
672
705
  heading,
673
706
  children
674
707
  ] });
675
708
  }
676
- return /* @__PURE__ */ jsxs7(BaseMenu.Group, { className: "flex flex-col", children: [
677
- /* @__PURE__ */ jsx13(BaseMenu.GroupLabel, { render: heading }),
709
+ return /* @__PURE__ */ jsxs8(BaseMenu.Group, { className: "flex flex-col", children: [
710
+ /* @__PURE__ */ jsx14(BaseMenu.GroupLabel, { render: heading }),
678
711
  children
679
712
  ] });
680
713
  }
681
714
  function MenuRow({ children, className }) {
682
- return /* @__PURE__ */ jsx13("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
715
+ return /* @__PURE__ */ jsx14("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
683
716
  }
684
717
 
685
718
  // src/ChipInput.tsx
686
- import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
719
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
687
720
  function InputChip({ label, leading, onRemove, className }) {
688
- return /* @__PURE__ */ jsxs8(
721
+ return /* @__PURE__ */ jsxs9(
689
722
  "div",
690
723
  {
691
724
  className: cn(
@@ -701,9 +734,9 @@ function InputChip({ label, leading, onRemove, className }) {
701
734
  className
702
735
  ),
703
736
  children: [
704
- leading && /* @__PURE__ */ jsx14("span", { className: "flex shrink-0 items-center", children: leading }),
705
- /* @__PURE__ */ jsx14("span", { className: "text-caption font-medium text-text-primary", children: label }),
706
- onRemove && /* @__PURE__ */ jsx14(
737
+ leading && /* @__PURE__ */ jsx15("span", { className: "flex shrink-0 items-center", children: leading }),
738
+ /* @__PURE__ */ jsx15("span", { className: "text-caption font-medium text-text-primary", children: label }),
739
+ onRemove && /* @__PURE__ */ jsx15(
707
740
  "button",
708
741
  {
709
742
  type: "button",
@@ -713,7 +746,7 @@ function InputChip({ label, leading, onRemove, className }) {
713
746
  },
714
747
  className: "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary",
715
748
  "aria-label": `Remove ${label}`,
716
- children: /* @__PURE__ */ jsx14(IconX2, { size: 10, stroke: 1.5 })
749
+ children: /* @__PURE__ */ jsx15(IconX2, { size: 10, stroke: 1.5 })
717
750
  }
718
751
  )
719
752
  ]
@@ -802,16 +835,16 @@ function ChipInput({
802
835
  }
803
836
  }
804
837
  }
805
- return /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
806
- /* @__PURE__ */ jsxs8(
838
+ return /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
839
+ /* @__PURE__ */ jsxs9(
807
840
  "div",
808
841
  {
809
842
  ref: wrapperRef,
810
843
  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",
811
844
  onClick: () => inputRef.current?.focus(),
812
845
  children: [
813
- value.map((o) => /* @__PURE__ */ jsx14(InputChip, { label: o.label, leading: chipLeading?.(o), onRemove: () => removeOption(o.id) }, o.id)),
814
- /* @__PURE__ */ jsx14(
846
+ value.map((o) => /* @__PURE__ */ jsx15(InputChip, { label: o.label, leading: chipLeading?.(o), onRemove: () => removeOption(o.id) }, o.id)),
847
+ /* @__PURE__ */ jsx15(
815
848
  "input",
816
849
  {
817
850
  ref: inputRef,
@@ -833,7 +866,7 @@ function ChipInput({
833
866
  }
834
867
  ),
835
868
  showDropdown && anchorRect && createPortal(
836
- /* @__PURE__ */ jsx14(
869
+ /* @__PURE__ */ jsx15(
837
870
  "div",
838
871
  {
839
872
  className: "fixed z-[60] overflow-y-auto bg-bg-elevated border border-border-default rounded-lg shadow-lg",
@@ -846,7 +879,7 @@ function ChipInput({
846
879
  }),
847
880
  width: anchorRect.width
848
881
  },
849
- children: matches.map((o, i) => /* @__PURE__ */ jsx14(
882
+ children: matches.map((o, i) => /* @__PURE__ */ jsx15(
850
883
  MenuItem,
851
884
  {
852
885
  size: "tall",
@@ -874,9 +907,26 @@ function ChipInput({
874
907
  import { useCallback, useRef as useRef2 } from "react";
875
908
 
876
909
  // src/Divider.tsx
877
- import { jsx as jsx15 } from "react/jsx-runtime";
878
- function Divider({ orientation = "horizontal", className }) {
879
- return /* @__PURE__ */ jsx15(
910
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
911
+ function Divider({ orientation = "horizontal", label, tone = "default", className }) {
912
+ if (label && orientation === "horizontal") {
913
+ const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
914
+ return /* @__PURE__ */ jsxs10(
915
+ "div",
916
+ {
917
+ role: "separator",
918
+ "aria-orientation": "horizontal",
919
+ "aria-label": label,
920
+ className: cn("flex shrink-0 items-center gap-2 mx-3", className),
921
+ children: [
922
+ /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
923
+ /* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
924
+ /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
925
+ ]
926
+ }
927
+ );
928
+ }
929
+ return /* @__PURE__ */ jsx16(
880
930
  "div",
881
931
  {
882
932
  role: "separator",
@@ -887,15 +937,15 @@ function Divider({ orientation = "horizontal", className }) {
887
937
  }
888
938
 
889
939
  // src/Person.tsx
890
- import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
940
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
891
941
  function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
892
942
  return (
893
943
  // gap-2: the face-to-name distance is one rule (8px) wherever a person
894
944
  // appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
895
945
  // row agree by construction.
896
- /* @__PURE__ */ jsxs9("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
897
- /* @__PURE__ */ jsx16(Avatar, { name, src: picture, size }),
898
- /* @__PURE__ */ jsx16("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
946
+ /* @__PURE__ */ jsxs11("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
947
+ /* @__PURE__ */ jsx17(Avatar, { name, src: picture, size }),
948
+ /* @__PURE__ */ jsx17("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
899
949
  ] })
900
950
  );
901
951
  }
@@ -903,10 +953,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
903
953
  // src/PersonTrigger.tsx
904
954
  import { Button as BaseButton3 } from "@base-ui/react/button";
905
955
  import { IconChevronDown } from "@tabler/icons-react";
906
- import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
956
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
907
957
  function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
908
958
  if (compact) {
909
- return /* @__PURE__ */ jsx17(
959
+ return /* @__PURE__ */ jsx18(
910
960
  BaseButton3,
911
961
  {
912
962
  type: "button",
@@ -915,11 +965,11 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
915
965
  "aria-label": props["aria-label"] ?? name ?? fallback,
916
966
  className: cn("cursor-pointer rounded-full", className),
917
967
  ...props,
918
- children: /* @__PURE__ */ jsx17(Avatar, { name, src: picture, size: size ?? 36 })
968
+ children: /* @__PURE__ */ jsx18(Avatar, { name, src: picture, size: size ?? 36 })
919
969
  }
920
970
  );
921
971
  }
922
- return /* @__PURE__ */ jsxs10(
972
+ return /* @__PURE__ */ jsxs12(
923
973
  BaseButton3,
924
974
  {
925
975
  type: "button",
@@ -937,18 +987,18 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
937
987
  ),
938
988
  ...props,
939
989
  children: [
940
- /* @__PURE__ */ jsx17(Person, { name, picture, fallback, size: size ?? 22 }),
941
- /* @__PURE__ */ jsx17(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
990
+ /* @__PURE__ */ jsx18(Person, { name, picture, fallback, size: size ?? 22 }),
991
+ /* @__PURE__ */ jsx18(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
942
992
  ]
943
993
  }
944
994
  );
945
995
  }
946
996
 
947
997
  // src/IdentityMenu.tsx
948
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
998
+ import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
949
999
  function IdentityPanel({ className, onClose = () => {
950
1000
  }, ...rest }) {
951
- return /* @__PURE__ */ jsx18(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx18(IdentityRows, { ...rest, onClose }) });
1001
+ return /* @__PURE__ */ jsx19(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx19(IdentityRows, { ...rest, onClose }) });
952
1002
  }
953
1003
  function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
954
1004
  const act = (action) => () => {
@@ -956,36 +1006,36 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
956
1006
  action();
957
1007
  };
958
1008
  const appRows = typeof children === "function" ? children(onClose) : children;
959
- return /* @__PURE__ */ jsxs11(Fragment2, { children: [
960
- /* @__PURE__ */ jsxs11(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
961
- /* @__PURE__ */ jsx18(MenuRow, { children: /* @__PURE__ */ jsx18(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
962
- /* @__PURE__ */ jsx18(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." }),
963
- me.email && /* @__PURE__ */ jsxs11(Note, { children: [
1009
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
1010
+ /* @__PURE__ */ jsxs13(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
1011
+ /* @__PURE__ */ jsx19(MenuRow, { children: /* @__PURE__ */ jsx19(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
1012
+ /* @__PURE__ */ jsx19(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." }),
1013
+ me.email && /* @__PURE__ */ jsxs13(Note, { children: [
964
1014
  me.email,
965
1015
  " \xB7 known to Estiva, never published to the relay"
966
1016
  ] })
967
1017
  ] }),
968
- relayUrl && /* @__PURE__ */ jsxs11(Fragment2, { children: [
969
- /* @__PURE__ */ jsx18(Divider, { className: "mx-0 my-2" }),
970
- /* @__PURE__ */ jsxs11(MenuSection, { label: "Workspace", children: [
971
- /* @__PURE__ */ jsx18(MenuRow, { children: /* @__PURE__ */ jsx18("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
972
- /* @__PURE__ */ jsx18(Note, { children: "Everyone on this relay shares this workspace, in every app." })
1018
+ relayUrl && /* @__PURE__ */ jsxs13(Fragment2, { children: [
1019
+ /* @__PURE__ */ jsx19(Divider, { className: "mx-0 my-2" }),
1020
+ /* @__PURE__ */ jsxs13(MenuSection, { label: "Workspace", children: [
1021
+ /* @__PURE__ */ jsx19(MenuRow, { children: /* @__PURE__ */ jsx19("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
1022
+ /* @__PURE__ */ jsx19(Note, { children: "Everyone on this relay shares this workspace, in every app." })
973
1023
  ] })
974
1024
  ] }),
975
- appRows && /* @__PURE__ */ jsxs11(Fragment2, { children: [
976
- /* @__PURE__ */ jsx18(Divider, { className: "mx-0 my-2" }),
1025
+ appRows && /* @__PURE__ */ jsxs13(Fragment2, { children: [
1026
+ /* @__PURE__ */ jsx19(Divider, { className: "mx-0 my-2" }),
977
1027
  appRows
978
1028
  ] }),
979
- signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx18(Divider, { className: "mx-0 my-2" }) : null,
980
- signedIn && idBase && /* @__PURE__ */ jsx18(
1029
+ signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx19(Divider, { className: "mx-0 my-2" }) : null,
1030
+ signedIn && idBase && /* @__PURE__ */ jsx19(
981
1031
  MenuItem,
982
1032
  {
983
1033
  label: "Edit your profile in Estiva ID",
984
1034
  onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
985
1035
  }
986
1036
  ),
987
- onCopyKey && /* @__PURE__ */ jsx18(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
988
- idBase && onSignOut && /* @__PURE__ */ jsx18(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
1037
+ onCopyKey && /* @__PURE__ */ jsx19(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
1038
+ idBase && onSignOut && /* @__PURE__ */ jsx19(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
989
1039
  ] });
990
1040
  }
991
1041
  function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
@@ -996,13 +1046,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
996
1046
  to be `relative`, because the panel was positioned against it; the panel
997
1047
  hangs from the trigger and portals now, so a positioning context here
998
1048
  would only be a lie about what this box does. */
999
- /* @__PURE__ */ jsx18("div", { className, children: /* @__PURE__ */ jsx18(
1049
+ /* @__PURE__ */ jsx19("div", { className, children: /* @__PURE__ */ jsx19(
1000
1050
  Menu,
1001
1051
  {
1002
1052
  align: "right",
1003
1053
  actionsRef: actions,
1004
1054
  className: "w-72",
1005
- trigger: /* @__PURE__ */ jsx18(
1055
+ trigger: /* @__PURE__ */ jsx19(
1006
1056
  PersonTrigger,
1007
1057
  {
1008
1058
  name: me.name,
@@ -1013,7 +1063,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
1013
1063
  "aria-label": compact ? "Account menu" : void 0
1014
1064
  }
1015
1065
  ),
1016
- children: /* @__PURE__ */ jsx18(
1066
+ children: /* @__PURE__ */ jsx19(
1017
1067
  IdentityRows,
1018
1068
  {
1019
1069
  me,
@@ -1031,25 +1081,25 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
1031
1081
  );
1032
1082
  }
1033
1083
  function Note({ children }) {
1034
- return /* @__PURE__ */ jsx18("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
1084
+ return /* @__PURE__ */ jsx19("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
1035
1085
  }
1036
1086
 
1037
1087
  // src/Field.tsx
1038
1088
  import { cloneElement, isValidElement } from "react";
1039
1089
  import { Field as BaseField } from "@base-ui/react/field";
1040
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1090
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1041
1091
  function Field({ label, required = false, helper, error, children }) {
1042
1092
  const control = required && isValidElement(children) ? cloneElement(children, {
1043
1093
  "aria-required": children.props["aria-required"] ?? true
1044
1094
  }) : children;
1045
- return /* @__PURE__ */ jsxs12(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
1046
- /* @__PURE__ */ jsxs12(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1095
+ return /* @__PURE__ */ jsxs14(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
1096
+ /* @__PURE__ */ jsxs14(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1047
1097
  label,
1048
- required && /* @__PURE__ */ jsx19("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1098
+ required && /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1049
1099
  ] }),
1050
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-1.5", children: [
1100
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1.5", children: [
1051
1101
  control,
1052
- error != null ? /* @__PURE__ */ jsx19(BaseField.Error, { match: true, className: "text-caption text-error-default", children: error }) : helper != null ? /* @__PURE__ */ jsx19(BaseField.Description, { className: "text-caption text-text-muted", children: helper }) : null
1102
+ error != null ? /* @__PURE__ */ jsx20(BaseField.Error, { match: true, className: "text-caption text-error-default", children: error }) : helper != null ? /* @__PURE__ */ jsx20(BaseField.Description, { className: "text-caption text-text-muted", children: helper }) : null
1053
1103
  ] })
1054
1104
  ] });
1055
1105
  }
@@ -1057,12 +1107,12 @@ function Field({ label, required = false, helper, error, children }) {
1057
1107
  // src/Select.tsx
1058
1108
  import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
1059
1109
  import { Select as BaseSelect } from "@base-ui/react/select";
1060
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1110
+ import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
1061
1111
  var GAP4 = 4;
1062
1112
  var VIEWPORT_PAD3 = 8;
1063
1113
  function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, className, ...aria }) {
1064
1114
  const selected = options.find((o) => o.value === value);
1065
- return /* @__PURE__ */ jsxs13(
1115
+ return /* @__PURE__ */ jsxs15(
1066
1116
  BaseSelect.Root,
1067
1117
  {
1068
1118
  value,
@@ -1070,7 +1120,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1070
1120
  disabled,
1071
1121
  modal: false,
1072
1122
  children: [
1073
- /* @__PURE__ */ jsxs13(
1123
+ /* @__PURE__ */ jsxs15(
1074
1124
  BaseSelect.Trigger,
1075
1125
  {
1076
1126
  "aria-label": ariaLabel,
@@ -1097,20 +1147,20 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1097
1147
  className
1098
1148
  ),
1099
1149
  children: [
1100
- /* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
1101
- selected?.leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: selected.leading }),
1102
- /* @__PURE__ */ jsx20(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
1150
+ /* @__PURE__ */ jsxs15("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
1151
+ selected?.leading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: selected.leading }),
1152
+ /* @__PURE__ */ jsx21(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
1103
1153
  ] }),
1104
- /* @__PURE__ */ jsx20(
1154
+ /* @__PURE__ */ jsx21(
1105
1155
  BaseSelect.Icon,
1106
1156
  {
1107
- render: /* @__PURE__ */ jsx20(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1157
+ render: /* @__PURE__ */ jsx21(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1108
1158
  }
1109
1159
  )
1110
1160
  ]
1111
1161
  }
1112
1162
  ),
1113
- /* @__PURE__ */ jsx20(BaseSelect.Portal, { children: /* @__PURE__ */ jsx20(
1163
+ /* @__PURE__ */ jsx21(BaseSelect.Portal, { children: /* @__PURE__ */ jsx21(
1114
1164
  BaseSelect.Positioner,
1115
1165
  {
1116
1166
  side: "bottom",
@@ -1119,30 +1169,30 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1119
1169
  collisionPadding: VIEWPORT_PAD3,
1120
1170
  alignItemWithTrigger: false,
1121
1171
  className: "z-50 data-[anchor-hidden]:hidden",
1122
- children: /* @__PURE__ */ jsx20(
1172
+ children: /* @__PURE__ */ jsx21(
1123
1173
  BaseSelect.Popup,
1124
1174
  {
1125
- className: "max-h-[min(288px,var(--available-height))] min-w-[var(--anchor-width)] overflow-y-auto rounded-lg border border-border-default bg-bg-elevated p-1 shadow-lg",
1126
- children: options.map((option) => /* @__PURE__ */ jsxs13(
1175
+ className: "min-w-[var(--anchor-width)] rounded-lg border border-border-default bg-bg-elevated p-1 shadow-lg",
1176
+ children: /* @__PURE__ */ jsx21(ScrollArea, { viewportClassName: "max-h-[calc(min(288px,var(--available-height))_-_0.5rem)]", contentClassName: "flex flex-col", children: options.map((option) => /* @__PURE__ */ jsxs15(
1127
1177
  BaseSelect.Item,
1128
1178
  {
1129
1179
  value: option.value,
1130
1180
  className: "flex h-9 cursor-pointer items-center justify-between gap-2 rounded-lg px-3 text-[14px] font-normal leading-[1.4] text-text-primary transition-colors data-[highlighted]:bg-bg-hover data-[selected]:font-medium",
1131
1181
  children: [
1132
- /* @__PURE__ */ jsxs13("span", { className: "flex min-w-0 items-center gap-2", children: [
1133
- option.leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: option.leading }),
1134
- /* @__PURE__ */ jsx20(BaseSelect.ItemText, { className: "truncate", children: option.label })
1182
+ /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-2", children: [
1183
+ option.leading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: option.leading }),
1184
+ /* @__PURE__ */ jsx21(BaseSelect.ItemText, { className: "truncate", children: option.label })
1135
1185
  ] }),
1136
- /* @__PURE__ */ jsx20(
1186
+ /* @__PURE__ */ jsx21(
1137
1187
  BaseSelect.ItemIndicator,
1138
1188
  {
1139
- render: /* @__PURE__ */ jsx20(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1189
+ render: /* @__PURE__ */ jsx21(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1140
1190
  }
1141
1191
  )
1142
1192
  ]
1143
1193
  },
1144
1194
  option.value
1145
- ))
1195
+ )) })
1146
1196
  }
1147
1197
  )
1148
1198
  }
@@ -1155,9 +1205,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1155
1205
  // src/TextInput.tsx
1156
1206
  import { forwardRef } from "react";
1157
1207
  import { Input } from "@base-ui/react/input";
1158
- import { jsx as jsx21 } from "react/jsx-runtime";
1208
+ import { jsx as jsx22 } from "react/jsx-runtime";
1159
1209
  var TextInput = forwardRef(function TextInput2({ className, type = "text", ...props }, ref) {
1160
- return /* @__PURE__ */ jsx21(
1210
+ return /* @__PURE__ */ jsx22(
1161
1211
  Input,
1162
1212
  {
1163
1213
  ref,
@@ -1178,13 +1228,13 @@ var TextInput = forwardRef(function TextInput2({ className, type = "text", ...pr
1178
1228
  // src/Textarea.tsx
1179
1229
  import { forwardRef as forwardRef2 } from "react";
1180
1230
  import { Field as BaseField2 } from "@base-ui/react/field";
1181
- import { jsx as jsx22 } from "react/jsx-runtime";
1231
+ import { jsx as jsx23 } from "react/jsx-runtime";
1182
1232
  var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
1183
- return /* @__PURE__ */ jsx22(
1233
+ return /* @__PURE__ */ jsx23(
1184
1234
  BaseField2.Control,
1185
1235
  {
1186
1236
  ref,
1187
- render: /* @__PURE__ */ jsx22("textarea", {}),
1237
+ render: /* @__PURE__ */ jsx23("textarea", {}),
1188
1238
  className: cn(
1189
1239
  "bg-bg-inset border border-border-default focus:border-border-focus rounded-lg px-3 py-2",
1190
1240
  "text-[14px] leading-[1.4] font-normal text-text-primary placeholder:text-text-muted",
@@ -1206,20 +1256,20 @@ import { useRef as useRef3 } from "react";
1206
1256
  import { Dialog } from "@base-ui/react/dialog";
1207
1257
  import { AlertDialog } from "@base-ui/react/alert-dialog";
1208
1258
  import { IconX as IconX3 } from "@tabler/icons-react";
1209
- import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
1259
+ import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
1210
1260
  function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, width = 502, alert = false }) {
1211
1261
  const Parts = alert ? AlertDialog : Dialog;
1212
1262
  const popupRef = useRef3(null);
1213
- return /* @__PURE__ */ jsx23(
1263
+ return /* @__PURE__ */ jsx24(
1214
1264
  Parts.Root,
1215
1265
  {
1216
1266
  open: true,
1217
1267
  onOpenChange: (open) => {
1218
1268
  if (!open) onClose();
1219
1269
  },
1220
- children: /* @__PURE__ */ jsxs14(Parts.Portal, { children: [
1221
- /* @__PURE__ */ jsx23(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1222
- /* @__PURE__ */ jsx23("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs14(
1270
+ children: /* @__PURE__ */ jsxs16(Parts.Portal, { children: [
1271
+ /* @__PURE__ */ jsx24(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1272
+ /* @__PURE__ */ jsx24("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs16(
1223
1273
  Parts.Popup,
1224
1274
  {
1225
1275
  ref: popupRef,
@@ -1228,17 +1278,17 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
1228
1278
  className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
1229
1279
  style: { width },
1230
1280
  children: [
1231
- /* @__PURE__ */ jsxs14("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
1232
- headerContent ?? /* @__PURE__ */ jsx23(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx23("span", {}), children: title }),
1233
- /* @__PURE__ */ jsx23(
1281
+ /* @__PURE__ */ jsxs16("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
1282
+ headerContent ?? /* @__PURE__ */ jsx24(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx24("span", {}), children: title }),
1283
+ /* @__PURE__ */ jsx24(
1234
1284
  Parts.Close,
1235
1285
  {
1236
- render: /* @__PURE__ */ jsx23(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx23(IconX3, { size: 16, stroke: 1.5 }) })
1286
+ render: /* @__PURE__ */ jsx24(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx24(IconX3, { size: 16, stroke: 1.5 }) })
1237
1287
  }
1238
1288
  )
1239
1289
  ] }),
1240
- /* @__PURE__ */ jsx23("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1241
- footer != null && /* @__PURE__ */ jsx23("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
1290
+ /* @__PURE__ */ jsx24("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1291
+ footer != null && /* @__PURE__ */ jsx24("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
1242
1292
  ]
1243
1293
  }
1244
1294
  ) })
@@ -1248,7 +1298,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
1248
1298
  }
1249
1299
 
1250
1300
  // src/ConfirmDialog.tsx
1251
- import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
1301
+ import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1252
1302
  function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
1253
1303
  const [busy, setBusy] = useState3(false);
1254
1304
  const confirm = async () => {
@@ -1260,16 +1310,16 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
1260
1310
  setBusy(false);
1261
1311
  }
1262
1312
  };
1263
- return /* @__PURE__ */ jsx24(
1313
+ return /* @__PURE__ */ jsx25(
1264
1314
  DialogShell,
1265
1315
  {
1266
1316
  alert: true,
1267
1317
  title,
1268
1318
  onClose,
1269
1319
  bodyClassName: "flex flex-col gap-3 text-body-2 text-text-primary",
1270
- footer: /* @__PURE__ */ jsxs15(Fragment3, { children: [
1271
- /* @__PURE__ */ jsx24(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
1272
- /* @__PURE__ */ jsx24(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
1320
+ footer: /* @__PURE__ */ jsxs17(Fragment3, { children: [
1321
+ /* @__PURE__ */ jsx25(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
1322
+ /* @__PURE__ */ jsx25(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
1273
1323
  ] }),
1274
1324
  children
1275
1325
  }
@@ -1280,7 +1330,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
1280
1330
  import { useEffect as useEffect2, useRef as useRef4, useState as useState4 } from "react";
1281
1331
  import { Field as BaseField3 } from "@base-ui/react/field";
1282
1332
  import { Input as Input2 } from "@base-ui/react/input";
1283
- import { jsx as jsx25 } from "react/jsx-runtime";
1333
+ import { jsx as jsx26 } from "react/jsx-runtime";
1284
1334
  function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
1285
1335
  const [editing, setEditing] = useState4(false);
1286
1336
  const [draft, setDraft] = useState4(value);
@@ -1338,7 +1388,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1338
1388
  written and never read. Read-only, this is a line of text: whatever
1339
1389
  names the region around it (a `Field`, a `Property`) names this too.
1340
1390
  */
1341
- /* @__PURE__ */ jsx25(
1391
+ /* @__PURE__ */ jsx26(
1342
1392
  "div",
1343
1393
  {
1344
1394
  className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
@@ -1348,11 +1398,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1348
1398
  );
1349
1399
  }
1350
1400
  if (editing) {
1351
- return multiline ? /* @__PURE__ */ jsx25(
1401
+ return multiline ? /* @__PURE__ */ jsx26(
1352
1402
  BaseField3.Control,
1353
1403
  {
1354
1404
  ref: fieldRef,
1355
- render: /* @__PURE__ */ jsx25("textarea", { rows: 4 }),
1405
+ render: /* @__PURE__ */ jsx26("textarea", { rows: 4 }),
1356
1406
  "aria-label": label,
1357
1407
  value: draft,
1358
1408
  disabled: busy,
@@ -1361,7 +1411,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1361
1411
  onBlur: () => void commit(),
1362
1412
  className: fieldClass
1363
1413
  }
1364
- ) : /* @__PURE__ */ jsx25(
1414
+ ) : /* @__PURE__ */ jsx26(
1365
1415
  Input2,
1366
1416
  {
1367
1417
  ref: fieldRef,
@@ -1375,7 +1425,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1375
1425
  }
1376
1426
  );
1377
1427
  }
1378
- return /* @__PURE__ */ jsx25(
1428
+ return /* @__PURE__ */ jsx26(
1379
1429
  "button",
1380
1430
  {
1381
1431
  type: "button",
@@ -1394,33 +1444,36 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1394
1444
 
1395
1445
  // src/EmptyState.tsx
1396
1446
  import { IconMessage2 } from "@tabler/icons-react";
1397
- import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
1398
- function EmptyState({ icon, message, className }) {
1399
- return /* @__PURE__ */ jsxs16("div", { className: cn("flex flex-col gap-2 items-center", className), children: [
1400
- /* @__PURE__ */ jsx26("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx26(IconMessage2, { size: 16, stroke: 1.5 }) }),
1401
- /* @__PURE__ */ jsx26("p", { className: "text-body-2 text-text-secondary text-center", children: message })
1447
+ import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
1448
+ function EmptyState({ icon, message, scope = "page", className }) {
1449
+ if (scope === "section") {
1450
+ return /* @__PURE__ */ jsx27("p", { className: cn("text-body-2 text-text-secondary", className), children: message });
1451
+ }
1452
+ return /* @__PURE__ */ jsxs18("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1453
+ /* @__PURE__ */ jsx27("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx27(IconMessage2, { size: 16, stroke: 1.5 }) }),
1454
+ /* @__PURE__ */ jsx27("p", { className: "text-body-2 text-text-secondary text-center", children: message })
1402
1455
  ] });
1403
1456
  }
1404
1457
 
1405
1458
  // src/Skeleton.tsx
1406
- import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
1459
+ import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
1407
1460
  function SkeletonBar({ className, style }) {
1408
- return /* @__PURE__ */ jsx27("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1461
+ return /* @__PURE__ */ jsx28("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1409
1462
  }
1410
1463
  var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
1411
1464
  function SkeletonRow({ barWidth = 130 }) {
1412
- return /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1413
- /* @__PURE__ */ jsx27(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1414
- /* @__PURE__ */ jsx27(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1465
+ return /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1466
+ /* @__PURE__ */ jsx28(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1467
+ /* @__PURE__ */ jsx28(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1415
1468
  ] });
1416
1469
  }
1417
1470
  function SkeletonList({ rows = 8, className }) {
1418
- return /* @__PURE__ */ jsx27("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx27(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1471
+ return /* @__PURE__ */ jsx28("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx28(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1419
1472
  }
1420
1473
 
1421
1474
  // src/Breadcrumb.tsx
1422
1475
  import { Fragment as Fragment4, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState5 } from "react";
1423
- import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
1476
+ import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
1424
1477
  function Breadcrumb({ items, className }) {
1425
1478
  const navRef = useRef5(null);
1426
1479
  const labelRefs = useRef5([]);
@@ -1440,36 +1493,38 @@ function Breadcrumb({ items, className }) {
1440
1493
  observer.observe(nav);
1441
1494
  return () => observer.disconnect();
1442
1495
  }, [measure, items]);
1443
- return /* @__PURE__ */ jsx28("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-[14px] leading-[140%]", className), children: items.map((item, index) => {
1496
+ return /* @__PURE__ */ jsx29("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-[14px] leading-[140%]", className), children: items.map((item, index) => {
1444
1497
  const last = index === items.length - 1;
1498
+ const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
1445
1499
  const text = cn(
1446
1500
  "truncate",
1447
1501
  // A mono crumb is a ref — the identity. It never gives up width to a
1448
1502
  // long name beside it (the LongName story always claimed "the ref
1449
1503
  // stays"; flexbox was squeezing it anyway until this line).
1450
1504
  item.mono && "shrink-0 font-mono text-[12px] leading-[120%]",
1451
- item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary"
1505
+ tone
1452
1506
  );
1453
1507
  const setLabelRef = (el) => {
1454
1508
  labelRefs.current[index] = el;
1455
1509
  };
1456
- const crumb = item.href ? /* @__PURE__ */ jsx28("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx28("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
1457
- return /* @__PURE__ */ jsxs18(Fragment4, { children: [
1458
- index > 0 && /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
1510
+ const crumb = item.href ? /* @__PURE__ */ jsx29("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx29("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
1511
+ return /* @__PURE__ */ jsxs20(Fragment4, { children: [
1512
+ index > 0 && /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
1513
+ item.icon && /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
1459
1514
  truncated.has(index) ? (
1460
1515
  // `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
1461
1516
  // must keep truncating inside it, or wrapping it would widen the
1462
1517
  // trail and the tooltip would never be needed again.
1463
- /* @__PURE__ */ jsx28(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
1518
+ /* @__PURE__ */ jsx29(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
1464
1519
  ) : crumb
1465
1520
  ] }, `${item.label}-${index}`);
1466
1521
  }) });
1467
1522
  }
1468
1523
 
1469
1524
  // src/NavItem.tsx
1470
- import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
1525
+ import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
1471
1526
  function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
1472
- return /* @__PURE__ */ jsxs19(
1527
+ return /* @__PURE__ */ jsxs21(
1473
1528
  "a",
1474
1529
  {
1475
1530
  href,
@@ -1484,9 +1539,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
1484
1539
  ),
1485
1540
  ...props,
1486
1541
  children: [
1487
- icon && /* @__PURE__ */ jsx29("span", { className: "flex shrink-0 items-center", children: icon }),
1488
- /* @__PURE__ */ jsx29("span", { className: "flex-1 truncate", children: label }),
1489
- count ? /* @__PURE__ */ jsx29(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx29("span", { className: "shrink-0 font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
1542
+ icon && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: icon }),
1543
+ /* @__PURE__ */ jsx30("span", { className: "flex-1 truncate", children: label }),
1544
+ count ? /* @__PURE__ */ jsx30(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx30("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
1490
1545
  ]
1491
1546
  }
1492
1547
  );
@@ -1495,7 +1550,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
1495
1550
  // src/Popover.tsx
1496
1551
  import { useMemo as useMemo2 } from "react";
1497
1552
  import { Popover as BasePopover } from "@base-ui/react/popover";
1498
- import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
1553
+ import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
1499
1554
  var GAP5 = 4;
1500
1555
  var VIEWPORT_PAD4 = 8;
1501
1556
  function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className }) {
@@ -1504,7 +1559,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1504
1559
  if (anchor instanceof Element) return anchor;
1505
1560
  return { getBoundingClientRect: () => anchor };
1506
1561
  }, [anchor]);
1507
- return /* @__PURE__ */ jsxs20(
1562
+ return /* @__PURE__ */ jsxs22(
1508
1563
  BasePopover.Root,
1509
1564
  {
1510
1565
  open,
@@ -1512,8 +1567,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1512
1567
  actionsRef,
1513
1568
  modal: false,
1514
1569
  children: [
1515
- trigger && /* @__PURE__ */ jsx30(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
1516
- /* @__PURE__ */ jsx30(BasePopover.Portal, { children: /* @__PURE__ */ jsx30(
1570
+ trigger && /* @__PURE__ */ jsx31(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
1571
+ /* @__PURE__ */ jsx31(BasePopover.Portal, { children: /* @__PURE__ */ jsx31(
1517
1572
  BasePopover.Positioner,
1518
1573
  {
1519
1574
  anchor: anchorTarget,
@@ -1522,15 +1577,15 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1522
1577
  sideOffset: GAP5,
1523
1578
  collisionPadding: VIEWPORT_PAD4,
1524
1579
  className: "z-50 data-[anchor-hidden]:hidden",
1525
- children: /* @__PURE__ */ jsx30(
1580
+ children: /* @__PURE__ */ jsx31(
1526
1581
  BasePopover.Popup,
1527
1582
  {
1528
1583
  "aria-label": ariaLabel,
1529
1584
  initialFocus: trigger ? void 0 : false,
1530
1585
  finalFocus,
1531
- className: cn("min-w-[180px] max-h-[var(--available-height)] overflow-y-auto outline-none", className),
1532
- render: /* @__PURE__ */ jsx30(MenuPanel, {}),
1533
- children
1586
+ className: cn("min-w-[180px] outline-none", className),
1587
+ render: /* @__PURE__ */ jsx31(MenuPanel, {}),
1588
+ children: /* @__PURE__ */ jsx31(ScrollArea, { viewportClassName: "max-h-[calc(var(--available-height)_-_1rem)]", contentClassName: "flex flex-col [&>[role=separator]]:mx-0", children })
1534
1589
  }
1535
1590
  )
1536
1591
  }
@@ -1542,9 +1597,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1542
1597
 
1543
1598
  // src/Toolbar.tsx
1544
1599
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
1545
- import { jsx as jsx31 } from "react/jsx-runtime";
1600
+ import { jsx as jsx32 } from "react/jsx-runtime";
1546
1601
  function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
1547
- const strip = /* @__PURE__ */ jsx31(
1602
+ const strip = /* @__PURE__ */ jsx32(
1548
1603
  BaseToolbar.Root,
1549
1604
  {
1550
1605
  "aria-label": ariaLabel,
@@ -1555,24 +1610,24 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
1555
1610
  }
1556
1611
  );
1557
1612
  if (!surface) return strip;
1558
- return /* @__PURE__ */ jsx31(MenuPanel, { className: "w-fit p-1", children: strip });
1613
+ return /* @__PURE__ */ jsx32(MenuPanel, { className: "w-fit p-1", children: strip });
1559
1614
  }
1560
1615
  function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
1561
- return /* @__PURE__ */ jsx31(
1616
+ return /* @__PURE__ */ jsx32(
1562
1617
  BaseToolbar.Button,
1563
1618
  {
1564
1619
  ref,
1565
1620
  disabled: disabled || !!disabledReason,
1566
1621
  focusableWhenDisabled: true,
1567
- render: /* @__PURE__ */ jsx31(IconButton, { disabled, disabledReason, ...props })
1622
+ render: /* @__PURE__ */ jsx32(IconButton, { disabled, disabledReason, ...props })
1568
1623
  }
1569
1624
  );
1570
1625
  }
1571
1626
  function ToolbarInput(props) {
1572
- return /* @__PURE__ */ jsx31(BaseToolbar.Input, { render: /* @__PURE__ */ jsx31(TextInput, {}), ...props });
1627
+ return /* @__PURE__ */ jsx32(BaseToolbar.Input, { render: /* @__PURE__ */ jsx32(TextInput, {}), ...props });
1573
1628
  }
1574
1629
  function ToolbarSeparator({ className }) {
1575
- return /* @__PURE__ */ jsx31(
1630
+ return /* @__PURE__ */ jsx32(
1576
1631
  BaseToolbar.Separator,
1577
1632
  {
1578
1633
  orientation: "vertical",
@@ -1582,9 +1637,9 @@ function ToolbarSeparator({ className }) {
1582
1637
  }
1583
1638
 
1584
1639
  // src/ReactionPicker.tsx
1585
- import { jsx as jsx32 } from "react/jsx-runtime";
1640
+ import { jsx as jsx33 } from "react/jsx-runtime";
1586
1641
  function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
1587
- return /* @__PURE__ */ jsx32(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
1642
+ return /* @__PURE__ */ jsx33(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
1588
1643
  /*
1589
1644
  A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
1590
1645
  would become the toolbar's item and the button inside it would never
@@ -1594,14 +1649,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
1594
1649
  The tooltip names it for a pointer, `aria-label` for everything else,
1595
1650
  and both say the meaning rather than the glyph.
1596
1651
  */
1597
- /* @__PURE__ */ jsx32(
1652
+ /* @__PURE__ */ jsx33(
1598
1653
  ToolbarButton,
1599
1654
  {
1600
1655
  "aria-label": option.label,
1601
1656
  tooltip: option.label,
1602
1657
  onClick: () => onSelect(option.emoji),
1603
1658
  className: "size-7 text-[18px] leading-none",
1604
- children: /* @__PURE__ */ jsx32("span", { "aria-hidden": "true", children: option.emoji })
1659
+ children: /* @__PURE__ */ jsx33("span", { "aria-hidden": "true", children: option.emoji })
1605
1660
  },
1606
1661
  option.emoji
1607
1662
  )
@@ -1610,23 +1665,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
1610
1665
 
1611
1666
  // src/PreviewCard.tsx
1612
1667
  import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
1613
- import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
1668
+ import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
1614
1669
  var GAP6 = 12;
1615
1670
  var VIEWPORT_PAD5 = 8;
1616
1671
  var OPEN_DELAY2 = 350;
1617
1672
  var CLOSE_DELAY = 200;
1618
1673
  function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, wrapperClassName }) {
1619
- return /* @__PURE__ */ jsxs21(BasePreviewCard.Root, { children: [
1620
- /* @__PURE__ */ jsx33(
1674
+ return /* @__PURE__ */ jsxs23(BasePreviewCard.Root, { children: [
1675
+ /* @__PURE__ */ jsx34(
1621
1676
  BasePreviewCard.Trigger,
1622
1677
  {
1623
1678
  delay,
1624
1679
  closeDelay,
1625
- render: /* @__PURE__ */ jsx33("span", { className: cn("inline-flex", wrapperClassName) }),
1680
+ render: /* @__PURE__ */ jsx34("span", { className: cn("inline-flex", wrapperClassName) }),
1626
1681
  children
1627
1682
  }
1628
1683
  ),
1629
- /* @__PURE__ */ jsx33(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx33(
1684
+ /* @__PURE__ */ jsx34(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx34(
1630
1685
  BasePreviewCard.Positioner,
1631
1686
  {
1632
1687
  side,
@@ -1634,12 +1689,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
1634
1689
  sideOffset: GAP6,
1635
1690
  collisionPadding: VIEWPORT_PAD5,
1636
1691
  className: "z-50 data-[anchor-hidden]:hidden",
1637
- children: /* @__PURE__ */ jsx33(
1692
+ children: /* @__PURE__ */ jsx34(
1638
1693
  BasePreviewCard.Popup,
1639
1694
  {
1640
- className: cn("w-[360px] max-h-[min(300px,var(--available-height))] gap-3 overflow-y-auto p-3 outline-none [&>*]:shrink-0", className),
1641
- render: /* @__PURE__ */ jsx33(MenuPanel, {}),
1642
- children: content
1695
+ className: cn("w-[360px] p-3 outline-none", className),
1696
+ render: /* @__PURE__ */ jsx34(MenuPanel, {}),
1697
+ children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3 [&>*]:shrink-0", children: content })
1643
1698
  }
1644
1699
  )
1645
1700
  }
@@ -1648,15 +1703,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
1648
1703
  }
1649
1704
 
1650
1705
  // src/Rail.tsx
1651
- import { jsx as jsx34 } from "react/jsx-runtime";
1706
+ import { jsx as jsx35 } from "react/jsx-runtime";
1652
1707
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
1653
- return /* @__PURE__ */ jsx34("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
1708
+ return /* @__PURE__ */ jsx35("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
1654
1709
  }
1655
1710
 
1656
1711
  // src/RailItem.tsx
1657
- import { jsx as jsx35, jsxs as jsxs22 } from "react/jsx-runtime";
1712
+ import { jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
1658
1713
  function RailItem({ href, icon, label, active = false, className, ...props }) {
1659
- return /* @__PURE__ */ jsxs22(
1714
+ return /* @__PURE__ */ jsxs24(
1660
1715
  "a",
1661
1716
  {
1662
1717
  href,
@@ -1664,14 +1719,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
1664
1719
  className: cn("group flex w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
1665
1720
  ...props,
1666
1721
  children: [
1667
- /* @__PURE__ */ jsx35(
1722
+ /* @__PURE__ */ jsx36(
1668
1723
  "div",
1669
1724
  {
1670
1725
  className: cn(
1671
1726
  "flex items-center justify-center rounded-lg p-2 transition-colors",
1672
1727
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
1673
1728
  ),
1674
- children: /* @__PURE__ */ jsx35(
1729
+ children: /* @__PURE__ */ jsx36(
1675
1730
  "span",
1676
1731
  {
1677
1732
  className: cn(
@@ -1683,52 +1738,49 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
1683
1738
  )
1684
1739
  }
1685
1740
  ),
1686
- /* @__PURE__ */ jsx35("span", { className: cn("text-center text-[9px] font-medium leading-[115%]", active ? "text-text-primary" : "text-text-secondary"), children: label })
1741
+ /* @__PURE__ */ jsx36("span", { className: cn("text-center text-[9px] font-medium leading-[115%]", active ? "text-text-primary" : "text-text-secondary"), children: label })
1687
1742
  ]
1688
1743
  }
1689
1744
  );
1690
1745
  }
1691
1746
 
1692
1747
  // src/Sidebar.tsx
1693
- import { jsx as jsx36 } from "react/jsx-runtime";
1748
+ import { jsx as jsx37 } from "react/jsx-runtime";
1694
1749
  function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
1695
- return /* @__PURE__ */ jsx36(
1750
+ return /* @__PURE__ */ jsx37(
1696
1751
  "nav",
1697
1752
  {
1698
1753
  "aria-label": ariaLabel,
1699
- className: cn(
1700
- "flex w-60 shrink-0 flex-col gap-px overflow-y-auto border-r border-border-default bg-bg-surface px-2.5 py-3",
1701
- className
1702
- ),
1703
- children
1754
+ className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
1755
+ children: /* @__PURE__ */ jsx37(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
1704
1756
  }
1705
1757
  );
1706
1758
  }
1707
1759
 
1708
1760
  // src/Property.tsx
1709
- import { jsx as jsx37, jsxs as jsxs23 } from "react/jsx-runtime";
1761
+ import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
1710
1762
  function Property({ label, layout = "row", children, className }) {
1711
1763
  if (layout === "stacked") {
1712
1764
  return (
1713
1765
  // gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
1714
1766
  // Peek's topic-details sections already sit at 12px, Ship's rail was
1715
1767
  // 6px, and unifying means the bigger, calmer one.
1716
- /* @__PURE__ */ jsxs23("div", { className: cn("flex flex-col gap-3", className), children: [
1717
- /* @__PURE__ */ jsx37("span", { className: "text-menu uppercase tracking-[0.08em] text-text-secondary", children: label }),
1768
+ /* @__PURE__ */ jsxs25("div", { className: cn("flex flex-col gap-3", className), children: [
1769
+ /* @__PURE__ */ jsx38("span", { className: "text-menu uppercase tracking-[0.08em] text-text-secondary", children: label }),
1718
1770
  children
1719
1771
  ] })
1720
1772
  );
1721
1773
  }
1722
- return /* @__PURE__ */ jsxs23("div", { className: cn("flex items-center gap-2", className), children: [
1723
- /* @__PURE__ */ jsx37("span", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
1774
+ return /* @__PURE__ */ jsxs25("div", { className: cn("flex items-center gap-2", className), children: [
1775
+ /* @__PURE__ */ jsx38("span", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
1724
1776
  children
1725
1777
  ] });
1726
1778
  }
1727
1779
 
1728
1780
  // src/Reaction.tsx
1729
- import { jsx as jsx38, jsxs as jsxs24 } from "react/jsx-runtime";
1781
+ import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
1730
1782
  function Reaction({ emoji, count, pressed = false, className, type, ...props }) {
1731
- return /* @__PURE__ */ jsxs24(
1783
+ return /* @__PURE__ */ jsxs26(
1732
1784
  "button",
1733
1785
  {
1734
1786
  type: type ?? "button",
@@ -1739,13 +1791,20 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
1739
1791
  "inline-flex h-6 items-center justify-center gap-1.5 rounded-full px-2",
1740
1792
  "border transition-colors",
1741
1793
  "disabled:cursor-not-allowed disabled:opacity-50",
1742
- pressed ? "border-accent-primary bg-accent-muted text-accent-primary hover:border-accent-hover" : "border-border-default bg-bg-inset text-text-primary hover:border-border-strong hover:bg-bg-hover",
1794
+ pressed ? (
1795
+ /* In the ship theme the accent on its own wash measures 2.70:1
1796
+ (Finding 4), and the count was the thing that vanished
1797
+ (Katerina, 2026-09-08). The number reads in the text colour
1798
+ there; the accent keeps the edge and the fill. Signal keeps
1799
+ Peek's blue-on-wash, which reads. */
1800
+ "border-accent-primary bg-accent-muted text-accent-primary hover:border-accent-hover ship:text-text-primary"
1801
+ ) : "border-border-default bg-bg-inset text-text-primary hover:border-border-strong hover:bg-bg-hover",
1743
1802
  className
1744
1803
  ),
1745
1804
  ...props,
1746
1805
  children: [
1747
- /* @__PURE__ */ jsx38("span", { "aria-hidden": "true", className: "shrink-0 text-[16px] leading-none", children: emoji }),
1748
- /* @__PURE__ */ jsx38("span", { className: "text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tabular-nums", children: count })
1806
+ /* @__PURE__ */ jsx39("span", { "aria-hidden": "true", className: "shrink-0 text-[16px] leading-none", children: emoji }),
1807
+ /* @__PURE__ */ jsx39("span", { className: "text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tabular-nums", children: count })
1749
1808
  ]
1750
1809
  }
1751
1810
  );
@@ -1754,9 +1813,9 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
1754
1813
  // src/SearchInput.tsx
1755
1814
  import "react";
1756
1815
  import { Input as Input3 } from "@base-ui/react/input";
1757
- import { jsx as jsx39, jsxs as jsxs25 } from "react/jsx-runtime";
1816
+ import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
1758
1817
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
1759
- return /* @__PURE__ */ jsxs25(
1818
+ return /* @__PURE__ */ jsxs27(
1760
1819
  "div",
1761
1820
  {
1762
1821
  className: cn(
@@ -1766,7 +1825,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
1766
1825
  className
1767
1826
  ),
1768
1827
  children: [
1769
- /* @__PURE__ */ jsx39(
1828
+ /* @__PURE__ */ jsx40(
1770
1829
  Input3,
1771
1830
  {
1772
1831
  className: "flex-1 min-w-0 bg-transparent text-input-value text-text-primary placeholder:text-text-muted outline-none",
@@ -1774,65 +1833,113 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
1774
1833
  ...props
1775
1834
  }
1776
1835
  ),
1777
- shortcut && /* @__PURE__ */ jsx39(Kbd, { children: shortcut })
1836
+ shortcut && /* @__PURE__ */ jsx40(Kbd, { children: shortcut })
1778
1837
  ]
1779
1838
  }
1780
1839
  );
1781
1840
  }
1782
1841
 
1783
1842
  // src/SectionHeader.tsx
1784
- import { useState as useState6 } from "react";
1785
1843
  import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
1786
- import { jsx as jsx40, jsxs as jsxs26 } from "react/jsx-runtime";
1787
- function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, actions, showActions = "hover", className }) {
1788
- const [isHovered, setIsHovered] = useState6(false);
1789
- return /* @__PURE__ */ jsxs26(
1844
+ import { useRender } from "@base-ui/react/use-render";
1845
+ import { Fragment as Fragment5, jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
1846
+ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, actions, showActions = "hover", render, className }) {
1847
+ const titleElement = useRender({
1848
+ render: render ?? (chevron ? /* @__PURE__ */ jsx41("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx41("span", {})),
1849
+ props: {
1850
+ // `text-left`: a button centres its text. `h-full` and `flex-1`: the
1851
+ // whole row up to the actions is the hit target, as it was when the
1852
+ // row itself carried the click.
1853
+ className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
1854
+ children: /* @__PURE__ */ jsxs28(Fragment5, { children: [
1855
+ chevron && /* @__PURE__ */ jsx41(
1856
+ IconChevronRight2,
1857
+ {
1858
+ size: 12,
1859
+ stroke: 1.5,
1860
+ className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
1861
+ }
1862
+ ),
1863
+ /* @__PURE__ */ jsx41(SectionLabel, { children: title })
1864
+ ] })
1865
+ }
1866
+ });
1867
+ return /* @__PURE__ */ jsxs28(
1790
1868
  "div",
1791
1869
  {
1792
1870
  className: cn(
1793
- "flex h-[32px] items-center justify-between rounded-lg px-2 transition-colors",
1794
- isHovered && "bg-bg-hover",
1795
- chevron && "cursor-pointer",
1871
+ "group flex h-[32px] items-center gap-1 rounded-lg px-2 transition-colors",
1872
+ // The fill says "this does something": a row with a toggle or actions
1873
+ // lights up, a fixed heading over rows does not (2026-09-09, the
1874
+ // Sidebar's fixed group).
1875
+ (chevron || actions && actions.length > 0) && "hover:bg-bg-hover",
1796
1876
  className
1797
1877
  ),
1798
- onClick: chevron ? onToggle : void 0,
1799
- onMouseEnter: () => setIsHovered(true),
1800
- onMouseLeave: () => setIsHovered(false),
1801
1878
  children: [
1802
- /* @__PURE__ */ jsxs26("div", { className: "flex shrink-0 items-center gap-1", children: [
1803
- chevron && /* @__PURE__ */ jsx40(
1804
- IconChevronRight2,
1805
- {
1806
- size: 12,
1807
- stroke: 1.5,
1808
- className: cn("text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
1809
- }
1810
- ),
1811
- /* @__PURE__ */ jsx40(SectionLabel, { children: title })
1812
- ] }),
1813
- (showActions === "always" || isHovered) && actions && actions.length > 0 && /* @__PURE__ */ jsx40("div", { className: "flex items-center gap-1", children: actions.map((action) => /* @__PURE__ */ jsx40(
1814
- IconButton,
1879
+ titleElement,
1880
+ actions && actions.length > 0 && /* @__PURE__ */ jsx41(
1881
+ "div",
1815
1882
  {
1816
- tooltip: action.tooltip,
1817
- "aria-label": action.tooltip,
1818
- onClick: (event) => {
1819
- event.stopPropagation();
1820
- action.onClick();
1821
- },
1822
- children: action.icon
1823
- },
1824
- action.tooltip
1825
- )) })
1883
+ className: cn(
1884
+ "-mr-1 flex shrink-0 items-center gap-1",
1885
+ showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
1886
+ ),
1887
+ children: actions.map((action) => /* @__PURE__ */ jsx41(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
1888
+ }
1889
+ )
1826
1890
  ]
1827
1891
  }
1828
1892
  );
1829
1893
  }
1830
1894
 
1895
+ // src/CollapsibleSection.tsx
1896
+ import { useState as useState6 } from "react";
1897
+ import { Collapsible } from "@base-ui/react/collapsible";
1898
+ import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
1899
+ var OPEN = "open";
1900
+ var CLOSED = "closed";
1901
+ function readStored(key) {
1902
+ if (!key) return void 0;
1903
+ try {
1904
+ const value = window.localStorage.getItem(key);
1905
+ return value === OPEN ? true : value === CLOSED ? false : void 0;
1906
+ } catch {
1907
+ return void 0;
1908
+ }
1909
+ }
1910
+ function writeStored(key, open) {
1911
+ if (!key) return;
1912
+ try {
1913
+ window.localStorage.setItem(key, open ? OPEN : CLOSED);
1914
+ } catch {
1915
+ }
1916
+ }
1917
+ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, actions, showActions, children, className, contentClassName }) {
1918
+ const [openState, setOpenState] = useState6(() => readStored(storageKey) ?? defaultOpen);
1919
+ const open = openProp ?? openState;
1920
+ const setOpen = (next) => {
1921
+ setOpenState(next);
1922
+ writeStored(storageKey, next);
1923
+ onOpenChange?.(next);
1924
+ };
1925
+ return /* @__PURE__ */ jsxs29(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
1926
+ /* @__PURE__ */ jsx42(SectionHeader, { title, chevron: true, isExpanded: open, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx42(Collapsible.Trigger, {}) }),
1927
+ /* @__PURE__ */ jsx42(
1928
+ Collapsible.Panel,
1929
+ {
1930
+ hiddenUntilFound: true,
1931
+ 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",
1932
+ children: /* @__PURE__ */ jsx42("div", { className: cn("flex flex-col", contentClassName), children })
1933
+ }
1934
+ )
1935
+ ] });
1936
+ }
1937
+
1831
1938
  // src/Tabs.tsx
1832
1939
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
1833
- import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
1940
+ import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
1834
1941
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
1835
- return /* @__PURE__ */ jsx41(
1942
+ return /* @__PURE__ */ jsx43(
1836
1943
  BaseTabs.Root,
1837
1944
  {
1838
1945
  value: active,
@@ -1840,14 +1947,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
1840
1947
  if (details.reason === "none") onChange(value);
1841
1948
  },
1842
1949
  className,
1843
- children: /* @__PURE__ */ jsx41(
1950
+ children: /* @__PURE__ */ jsx43(
1844
1951
  BaseTabs.List,
1845
1952
  {
1846
1953
  activateOnFocus: true,
1847
1954
  "aria-label": aria["aria-label"],
1848
1955
  "aria-labelledby": aria["aria-labelledby"],
1849
1956
  className: "flex items-center gap-2",
1850
- children: tabs.map((tab) => /* @__PURE__ */ jsxs27(
1957
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs30(
1851
1958
  BaseTabs.Tab,
1852
1959
  {
1853
1960
  value: tab.id,
@@ -1860,9 +1967,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
1860
1967
  ),
1861
1968
  children: [
1862
1969
  tab.icon,
1863
- /* @__PURE__ */ jsxs27("span", { className: "flex items-baseline", children: [
1970
+ /* @__PURE__ */ jsxs30("span", { className: "flex items-baseline", children: [
1864
1971
  tab.label,
1865
- tab.count !== void 0 ? /* @__PURE__ */ jsx41("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
1972
+ tab.count !== void 0 ? /* @__PURE__ */ jsx43("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
1866
1973
  ] })
1867
1974
  ]
1868
1975
  },
@@ -1878,7 +1985,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
1878
1985
  import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo3, useState as useState7 } from "react";
1879
1986
  import { createPortal as createPortal2 } from "react-dom";
1880
1987
  import { IconCircleCheck } from "@tabler/icons-react";
1881
- import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
1988
+ import { jsx as jsx44, jsxs as jsxs31 } from "react/jsx-runtime";
1882
1989
  var SURFACE_STYLES = {
1883
1990
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
1884
1991
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
@@ -1896,7 +2003,7 @@ var ACTION_BORDER_STYLES = {
1896
2003
  };
1897
2004
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
1898
2005
  const hasAction = !!(actionLabel && onAction);
1899
- return /* @__PURE__ */ jsxs28(
2006
+ return /* @__PURE__ */ jsxs31(
1900
2007
  "div",
1901
2008
  {
1902
2009
  className: cn(
@@ -1908,11 +2015,11 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
1908
2015
  className
1909
2016
  ),
1910
2017
  children: [
1911
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2 shrink-0", children: [
1912
- leadingIcon && /* @__PURE__ */ jsx42(IconCircleCheck, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
1913
- /* @__PURE__ */ jsx42("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
2018
+ /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-2 shrink-0", children: [
2019
+ leadingIcon && /* @__PURE__ */ jsx44(IconCircleCheck, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
2020
+ /* @__PURE__ */ jsx44("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
1914
2021
  ] }),
1915
- hasAction && /* @__PURE__ */ jsx42(
2022
+ hasAction && /* @__PURE__ */ jsx44(
1916
2023
  "button",
1917
2024
  {
1918
2025
  type: "button",
@@ -1922,7 +2029,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
1922
2029
  ACTION_BORDER_STYLES[type],
1923
2030
  type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
1924
2031
  ),
1925
- children: /* @__PURE__ */ jsx42("span", { className: "font-medium text-[12px] leading-[12px] text-text-primary whitespace-nowrap", children: actionLabel })
2032
+ children: /* @__PURE__ */ jsx44("span", { className: "font-medium text-[12px] leading-[12px] text-text-primary whitespace-nowrap", children: actionLabel })
1926
2033
  }
1927
2034
  )
1928
2035
  ]
@@ -1949,10 +2056,10 @@ function ToastProvider({ children }) {
1949
2056
  return () => clearTimeout(timer);
1950
2057
  }, [toast]);
1951
2058
  const value = useMemo3(() => ({ showToast, dismissToast }), [showToast, dismissToast]);
1952
- return /* @__PURE__ */ jsxs28(ToastContext.Provider, { value, children: [
2059
+ return /* @__PURE__ */ jsxs31(ToastContext.Provider, { value, children: [
1953
2060
  children,
1954
2061
  toast && createPortal2(
1955
- /* @__PURE__ */ jsx42("div", { className: "fixed bottom-4 left-4 z-[100] pointer-events-none", children: /* @__PURE__ */ jsx42(
2062
+ /* @__PURE__ */ jsx44("div", { className: "fixed bottom-4 left-4 z-[100] pointer-events-none", children: /* @__PURE__ */ jsx44(
1956
2063
  Toast,
1957
2064
  {
1958
2065
  className: "pointer-events-auto",
@@ -1985,6 +2092,7 @@ export {
1985
2092
  Checkbox,
1986
2093
  Chip,
1987
2094
  ChipInput,
2095
+ CollapsibleSection,
1988
2096
  ConfirmDialog,
1989
2097
  DialogShell,
1990
2098
  Divider,
@@ -2013,6 +2121,7 @@ export {
2013
2121
  RailItem,
2014
2122
  Reaction,
2015
2123
  ReactionPicker,
2124
+ ScrollArea,
2016
2125
  SearchInput,
2017
2126
  SectionHeader,
2018
2127
  SectionLabel,