@estiva-app/ui 0.57.4 → 0.59.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 (65) hide show
  1. package/dist/CommandPalette.d.ts.map +1 -1
  2. package/dist/ComposerTriggers.d.ts +13 -1
  3. package/dist/ComposerTriggers.d.ts.map +1 -1
  4. package/dist/ContainerHeader.d.ts.map +1 -1
  5. package/dist/DialogShell.d.ts.map +1 -1
  6. package/dist/Kbd.d.ts.map +1 -1
  7. package/dist/MembersDialog.d.ts +57 -0
  8. package/dist/MembersDialog.d.ts.map +1 -0
  9. package/dist/MembersPill.d.ts +22 -0
  10. package/dist/MembersPill.d.ts.map +1 -0
  11. package/dist/NavItem.d.ts.map +1 -1
  12. package/dist/SectionHeader.d.ts +7 -1
  13. package/dist/SectionHeader.d.ts.map +1 -1
  14. package/dist/ShowMore.d.ts +27 -0
  15. package/dist/ShowMore.d.ts.map +1 -0
  16. package/dist/Tabs.d.ts +2 -0
  17. package/dist/Tabs.d.ts.map +1 -1
  18. package/dist/editor.js +4 -4
  19. package/dist/editor.js.map +2 -2
  20. package/dist/eslint/index.js +1 -0
  21. package/dist/eslint/index.js.map +2 -2
  22. package/dist/eslint/no-restyled-part.d.ts.map +1 -1
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1150 -994
  26. package/dist/index.js.map +4 -4
  27. package/dist/looks.d.ts +4 -0
  28. package/dist/looks.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/registry.json +212 -8
  31. package/src/CommandPalette.tsx +2 -1
  32. package/src/ComposerTriggers.mdx +7 -0
  33. package/src/ComposerTriggers.stories.tsx +43 -4
  34. package/src/ComposerTriggers.test.tsx +33 -0
  35. package/src/ComposerTriggers.tsx +17 -5
  36. package/src/ContainerHeader.mdx +1 -1
  37. package/src/ContainerHeader.tsx +3 -2
  38. package/src/DialogShell.tsx +2 -0
  39. package/src/Kbd.tsx +4 -2
  40. package/src/ListColumn.mdx +1 -1
  41. package/src/MembersDialog.mdx +69 -0
  42. package/src/MembersDialog.stories.tsx +68 -0
  43. package/src/MembersDialog.test.tsx +69 -0
  44. package/src/MembersDialog.tsx +184 -0
  45. package/src/MembersPill.mdx +45 -0
  46. package/src/MembersPill.stories.tsx +38 -0
  47. package/src/MembersPill.tsx +35 -0
  48. package/src/NavItem.tsx +3 -2
  49. package/src/SectionHeader.mdx +6 -4
  50. package/src/SectionHeader.stories.tsx +7 -2
  51. package/src/SectionHeader.test.tsx +6 -0
  52. package/src/SectionHeader.tsx +10 -2
  53. package/src/ShowMore.mdx +62 -0
  54. package/src/ShowMore.stories.tsx +39 -0
  55. package/src/ShowMore.test.tsx +44 -0
  56. package/src/ShowMore.tsx +63 -0
  57. package/src/Tabs.mdx +5 -0
  58. package/src/Tabs.stories.tsx +15 -0
  59. package/src/Tabs.test.tsx +8 -0
  60. package/src/Tabs.tsx +12 -0
  61. package/src/eslint/no-restyled-part.ts +1 -0
  62. package/src/index.ts +3 -0
  63. package/src/looks.ts +6 -0
  64. package/src/registry/registry.test.ts +4 -4
  65. package/stories/Choosing.mdx +4 -1
package/dist/index.js CHANGED
@@ -287,7 +287,9 @@ var FIELD_SIZE_CLASSES = {
287
287
  };
288
288
  var FIELD_SHELL_CLASSES = "bg-bg-field border border-border-field shadow-field hover:border-border-strong group-hover/field:border-border-strong rounded-lg transition-colors";
289
289
  var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
290
+ var COUNT_TEXT_CLASSES = "font-mono text-caption tabular-nums text-text-muted";
290
291
  var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums";
292
+ var MONO_CAPTION_CLASSES = "text-caption text-text-secondary signal:font-mono signal:text-small";
291
293
  var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
292
294
  var SIDEBAR_ROW_CLASSES = "rounded-lg transition-colors";
293
295
  var SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
@@ -312,8 +314,9 @@ function Kbd({ children, className, tone = "default" }) {
312
314
  "kbd",
313
315
  {
314
316
  className: cn(
315
- "inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-sm border border-border-strong bg-bg-inset px-1 py-px font-sans text-caption text-text-secondary",
316
- "signal:border-b-2 signal:pt-[2px] signal:pb-px signal:bg-bg-wash signal:font-mono signal:text-small",
317
+ "inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-sm border border-border-strong bg-bg-inset px-1 py-px font-sans",
318
+ MONO_CAPTION_CLASSES,
319
+ "signal:border-b-2 signal:pt-[2px] signal:pb-px signal:bg-bg-wash",
317
320
  "ship:border-b-2 ship:pt-[2px] ship:pb-px ship:bg-bg-wash ship:font-mono ship:text-small",
318
321
  // Leaf sets its keys in mono, as Signal does (Katerina, 28 September): the type, not the key's shape.
319
322
  "leaf:font-mono leaf:text-small",
@@ -858,9 +861,6 @@ function AvatarGroup({ members, size = 24 }) {
858
861
  )) });
859
862
  }
860
863
 
861
- // src/Banner.tsx
862
- import { IconX as IconX3 } from "@tabler/icons-react";
863
-
864
864
  // src/Button.tsx
865
865
  import { Button as BaseButton3 } from "@base-ui/react/button";
866
866
  import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
@@ -928,31 +928,55 @@ function Button({
928
928
  return disabledReason ? /* @__PURE__ */ jsx14(TooltipTrigger, { label: disabledReason, children: button }) : button;
929
929
  }
930
930
 
931
- // src/Banner.tsx
931
+ // src/MembersPill.tsx
932
932
  import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
933
- var TONE_STYLES = {
934
- ok: "bg-success-muted text-success-default",
935
- error: "bg-error-muted text-error-default",
936
- info: "bg-info-muted text-info-default",
937
- warning: "bg-warning-muted text-warning-default"
933
+ function MembersPill({ members, count, onClick, className }) {
934
+ const total = count ?? members.length;
935
+ if (total === 0) return null;
936
+ return /* @__PURE__ */ jsxs9(Button, { variant: "outlined", "aria-label": `${total} ${total === 1 ? "member" : "members"}`, disabled: !onClick, onClick, className: cn("gap-2 pl-[3px] pr-2", className), children: [
937
+ /* @__PURE__ */ jsx15(AvatarGroup, { members }),
938
+ /* @__PURE__ */ jsx15("span", { className: cn(MONO_CAPTION_CLASSES, "signal:tabular-nums"), children: total })
939
+ ] });
940
+ }
941
+
942
+ // src/MembersDialog.tsx
943
+ import { useId, useState as useState3 } from "react";
944
+ import { IconArrowLeft, IconUserMinus, IconUserPlus } from "@tabler/icons-react";
945
+
946
+ // src/Chip.tsx
947
+ import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
948
+ var typeStyles = {
949
+ neutral: "bg-bg-inset text-text-primary",
950
+ brand: "bg-accent-muted text-accent-text signal:border signal:border-accent-outline",
951
+ info: "bg-info-muted text-info-default signal:border signal:border-info-outline",
952
+ warning: "bg-warning-muted text-warning-default signal:border signal:border-warning-outline signal:shadow-glow-warning",
953
+ success: "bg-success-muted text-success-default signal:border signal:border-success-outline",
954
+ error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
938
955
  };
939
- function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismiss", className }) {
940
- const role = tone === "error" ? "alert" : "status";
941
- if (!onDismiss && !icon && !action) {
942
- return /* @__PURE__ */ jsx15("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
943
- }
944
- const oneLine = Boolean(icon || action);
945
- return /* @__PURE__ */ jsxs9("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
946
- icon && /* @__PURE__ */ jsx15("span", { className: "flex shrink-0", children: icon }),
947
- /* @__PURE__ */ jsx15("span", { className: cn("min-w-0 flex-1", oneLine && "truncate"), children }),
948
- action && /* @__PURE__ */ jsx15(Button, { variant: "muted", size: "small", className: "shrink-0", onClick: action.onClick, children: action.label }),
949
- onDismiss && /* @__PURE__ */ jsx15(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx15(IconX3, { size: 16, stroke: 1.5 }) })
956
+ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, href, onClick, className }) {
957
+ const classes = 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);
958
+ const inside = /* @__PURE__ */ jsxs10(Fragment3, { children: [
959
+ leadingIcon && /* @__PURE__ */ jsx16("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
960
+ label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
961
+ // of growing past it — Ship's project chip on an issue row
962
+ // (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
963
+ // `truncate`, because `truncate` is `overflow: hidden` on both axes and
964
+ // the label's line box (11px under Signal) is tighter than its glyphs —
965
+ // the screenshot diff caught every descender cut off. `clip` is the
966
+ // one overflow that leaves the other axis visible. A chip with no cap
967
+ // draws exactly as before.
968
+ /* @__PURE__ */ jsx16("span", { className: cn("min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap signal:tracking-wide", CHIP_TEXT_CLASSES), children: label }),
969
+ trailingIcon && /* @__PURE__ */ jsx16("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
950
970
  ] });
971
+ if (href) return /* @__PURE__ */ jsx16("a", { href, onClick, className: cn("relative", classes), children: inside });
972
+ return /* @__PURE__ */ jsx16("div", { className: classes, children: inside });
951
973
  }
952
974
 
953
- // src/BlockHandle.tsx
954
- import { useCallback, useEffect as useEffect2, useRef as useRef3, useState as useState2 } from "react";
955
- import { IconGripVertical } from "@tabler/icons-react";
975
+ // src/ChipInput.tsx
976
+ import { useMemo, useState as useState2 } from "react";
977
+ import { Button as BaseButton4 } from "@base-ui/react/button";
978
+ import { Combobox } from "@base-ui/react/combobox";
979
+ import { IconX as IconX3 } from "@tabler/icons-react";
956
980
 
957
981
  // src/Menu.tsx
958
982
  import { createContext as createContext4, useContext as useContext4 } from "react";
@@ -962,27 +986,27 @@ import { Menu as BaseMenu } from "@base-ui/react/menu";
962
986
  // src/Divider.tsx
963
987
  import { createContext as createContext3, useContext as useContext3 } from "react";
964
988
  import { Separator } from "@base-ui/react/separator";
965
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
989
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
966
990
  var DividerInPanel = createContext3(false);
967
991
  function Divider({ orientation = "horizontal", label, tone = "default", className }) {
968
992
  const inset = useContext3(DividerInPanel) ? "mx-0" : "mx-3";
969
993
  if (label && orientation === "horizontal") {
970
994
  const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
971
- return /* @__PURE__ */ jsxs10(
995
+ return /* @__PURE__ */ jsxs11(
972
996
  Separator,
973
997
  {
974
998
  orientation: "horizontal",
975
999
  "aria-label": label,
976
1000
  className: cn("flex shrink-0 items-center gap-2", inset, className),
977
1001
  children: [
978
- /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
979
- /* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
980
- /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
1002
+ /* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
1003
+ /* @__PURE__ */ jsx17("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
1004
+ /* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
981
1005
  ]
982
1006
  }
983
1007
  );
984
1008
  }
985
- return /* @__PURE__ */ jsx16(
1009
+ return /* @__PURE__ */ jsx17(
986
1010
  Separator,
987
1011
  {
988
1012
  orientation,
@@ -998,7 +1022,7 @@ function triggerDisabled(trigger) {
998
1022
  }
999
1023
 
1000
1024
  // src/SectionLabel.tsx
1001
- import { jsx as jsx17 } from "react/jsx-runtime";
1025
+ import { jsx as jsx18 } from "react/jsx-runtime";
1002
1026
  function SectionLabel({
1003
1027
  children,
1004
1028
  tone = "primary",
@@ -1006,7 +1030,7 @@ function SectionLabel({
1006
1030
  folds = false,
1007
1031
  className
1008
1032
  }) {
1009
- return /* @__PURE__ */ jsx17(
1033
+ return /* @__PURE__ */ jsx18(
1010
1034
  "span",
1011
1035
  {
1012
1036
  className: cn(
@@ -1027,10 +1051,10 @@ function SectionLabel({
1027
1051
  }
1028
1052
 
1029
1053
  // src/Menu.tsx
1030
- import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
1054
+ import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1031
1055
  var MenuContext = createContext4(null);
1032
1056
  function MenuPanel({ children, className, ...props }) {
1033
- return /* @__PURE__ */ jsx18(
1057
+ return /* @__PURE__ */ jsx19(
1034
1058
  "div",
1035
1059
  {
1036
1060
  className: cn(
@@ -1062,7 +1086,7 @@ var VIEWPORT_PAD2 = 8;
1062
1086
  var HOVER_OPEN_DELAY = 0;
1063
1087
  var HOVER_CLOSE_DELAY = 150;
1064
1088
  function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
1065
- return /* @__PURE__ */ jsxs11(
1089
+ return /* @__PURE__ */ jsxs12(
1066
1090
  BaseMenu.Root,
1067
1091
  {
1068
1092
  open,
@@ -1070,7 +1094,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
1070
1094
  actionsRef,
1071
1095
  modal: false,
1072
1096
  children: [
1073
- /* @__PURE__ */ jsx18(
1097
+ /* @__PURE__ */ jsx19(
1074
1098
  BaseMenu.Trigger,
1075
1099
  {
1076
1100
  render: trigger,
@@ -1080,7 +1104,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
1080
1104
  closeDelay: HOVER_CLOSE_DELAY
1081
1105
  }
1082
1106
  ),
1083
- /* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
1107
+ /* @__PURE__ */ jsx19(BaseMenu.Portal, { children: /* @__PURE__ */ jsx19(
1084
1108
  BaseMenu.Positioner,
1085
1109
  {
1086
1110
  side: "bottom",
@@ -1088,13 +1112,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
1088
1112
  sideOffset: GAP2,
1089
1113
  collisionPadding: VIEWPORT_PAD2,
1090
1114
  className: "z-50 data-[anchor-hidden]:hidden",
1091
- children: /* @__PURE__ */ jsx18(
1115
+ children: /* @__PURE__ */ jsx19(
1092
1116
  BaseMenu.Popup,
1093
1117
  {
1094
1118
  "data-interactive": true,
1095
1119
  className: cn("min-w-[180px] outline-none p-0", className),
1096
- render: /* @__PURE__ */ jsx18(MenuPanel, {}),
1097
- children: /* @__PURE__ */ jsx18(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col gap-0.5 p-2", contentClassName), children: /* @__PURE__ */ jsx18(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx18(DividerInPanel.Provider, { value: true, children }) }) })
1120
+ render: /* @__PURE__ */ jsx19(MenuPanel, {}),
1121
+ children: /* @__PURE__ */ jsx19(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col gap-0.5 p-2", contentClassName), children: /* @__PURE__ */ jsx19(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx19(DividerInPanel.Provider, { value: true, children }) }) })
1098
1122
  }
1099
1123
  )
1100
1124
  }
@@ -1110,20 +1134,20 @@ function MenuSub({ label, leading, selected, children, className }) {
1110
1134
  '[@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".'
1111
1135
  );
1112
1136
  }
1113
- return /* @__PURE__ */ jsxs11(BaseMenu.SubmenuRoot, { children: [
1114
- /* @__PURE__ */ jsx18(
1137
+ return /* @__PURE__ */ jsxs12(BaseMenu.SubmenuRoot, { children: [
1138
+ /* @__PURE__ */ jsx19(
1115
1139
  BaseMenu.SubmenuTrigger,
1116
1140
  {
1117
1141
  openOnHover: true,
1118
1142
  delay: 0,
1119
1143
  closeDelay: 150,
1120
1144
  nativeButton: true,
1121
- render: /* @__PURE__ */ jsx18("button", { type: "button" }),
1145
+ render: /* @__PURE__ */ jsx19("button", { type: "button" }),
1122
1146
  className: menuItemClassName({ size: "default", selected }),
1123
- children: /* @__PURE__ */ jsx18(MenuItemBody, { label, leading, submenu: true })
1147
+ children: /* @__PURE__ */ jsx19(MenuItemBody, { label, leading, submenu: true })
1124
1148
  }
1125
1149
  ),
1126
- /* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
1150
+ /* @__PURE__ */ jsx19(BaseMenu.Portal, { children: /* @__PURE__ */ jsx19(
1127
1151
  BaseMenu.Positioner,
1128
1152
  {
1129
1153
  side: "inline-end",
@@ -1131,7 +1155,7 @@ function MenuSub({ label, leading, selected, children, className }) {
1131
1155
  sideOffset: GAP2,
1132
1156
  collisionPadding: VIEWPORT_PAD2,
1133
1157
  className: "z-50 data-[anchor-hidden]:hidden",
1134
- children: /* @__PURE__ */ jsx18(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx18(MenuPanel, {}), children })
1158
+ children: /* @__PURE__ */ jsx19(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx19(MenuPanel, {}), children })
1135
1159
  }
1136
1160
  ) })
1137
1161
  ] });
@@ -1166,25 +1190,25 @@ function menuItemClassName({ size, selected, className }) {
1166
1190
  );
1167
1191
  }
1168
1192
  function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
1169
- 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);
1170
- return /* @__PURE__ */ jsxs11(Fragment3, { children: [
1171
- leading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: leading }),
1172
- children ?? /* @__PURE__ */ jsxs11("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
1173
- /* @__PURE__ */ jsx18("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
1174
- description && /* @__PURE__ */ jsx18("span", { className: "truncate text-caption text-text-secondary", children: description })
1193
+ 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);
1194
+ return /* @__PURE__ */ jsxs12(Fragment4, { children: [
1195
+ leading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: leading }),
1196
+ children ?? /* @__PURE__ */ jsxs12("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
1197
+ /* @__PURE__ */ jsx19("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
1198
+ description && /* @__PURE__ */ jsx19("span", { className: "truncate text-caption text-text-secondary", children: description })
1175
1199
  ] }),
1176
1200
  (edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
1177
1201
  // the wider of the two and never changes, so revealing the hint moves
1178
1202
  // nothing. No transition here either — the hint switches on the same
1179
1203
  // :hover / `selected` as the fill, in the same frame.
1180
- /* @__PURE__ */ jsxs11("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
1181
- 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 }),
1182
- 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 })
1204
+ /* @__PURE__ */ jsxs12("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
1205
+ 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 }),
1206
+ 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 })
1183
1207
  ] })
1184
1208
  ] });
1185
1209
  }
1186
1210
  function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
1187
- const body = /* @__PURE__ */ jsx18(
1211
+ const body = /* @__PURE__ */ jsx19(
1188
1212
  MenuItemBody,
1189
1213
  {
1190
1214
  label,
@@ -1202,13 +1226,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
1202
1226
  );
1203
1227
  const rowClassName = menuItemClassName({ size, selected, className });
1204
1228
  if (!useContext4(MenuContext)) {
1205
- return /* @__PURE__ */ jsx18("button", { type: "button", className: rowClassName, ...props, children: body });
1229
+ return /* @__PURE__ */ jsx19("button", { type: "button", className: rowClassName, ...props, children: body });
1206
1230
  }
1207
- return /* @__PURE__ */ jsx18(
1231
+ return /* @__PURE__ */ jsx19(
1208
1232
  BaseMenu.Item,
1209
1233
  {
1210
1234
  nativeButton: true,
1211
- render: /* @__PURE__ */ jsx18("button", { type: "button" }),
1235
+ render: /* @__PURE__ */ jsx19("button", { type: "button" }),
1212
1236
  className: rowClassName,
1213
1237
  ...props,
1214
1238
  children: body
@@ -1216,166 +1240,661 @@ function MenuItem({ label, children, size = "default", description, leading, tra
1216
1240
  );
1217
1241
  }
1218
1242
  function EnterHint({ target }) {
1219
- return /* @__PURE__ */ jsxs11("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
1220
- /* @__PURE__ */ jsx18(Kbd, { children: "\u21A9 Enter" }),
1221
- target && /* @__PURE__ */ jsx18("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider leaf:font-mono leaf:text-small leaf:tracking-wider", children: target })
1243
+ return /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
1244
+ /* @__PURE__ */ jsx19(Kbd, { children: "\u21A9 Enter" }),
1245
+ target && /* @__PURE__ */ jsx19("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider leaf:font-mono leaf:text-small leaf:tracking-wider", children: target })
1222
1246
  ] });
1223
1247
  }
1224
1248
  function MenuSection({ label, children, className }) {
1225
1249
  const inMenu = useContext4(MenuContext) !== null;
1226
- const heading = /* @__PURE__ */ jsx18("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx18(SectionLabel, { tone: "secondary", children: label }) });
1250
+ const heading = /* @__PURE__ */ jsx19("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx19(SectionLabel, { tone: "secondary", children: label }) });
1227
1251
  if (!inMenu) {
1228
- return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-0.5", children: [
1252
+ return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-0.5", children: [
1229
1253
  heading,
1230
1254
  children
1231
1255
  ] });
1232
1256
  }
1233
- return /* @__PURE__ */ jsxs11(BaseMenu.Group, { className: "flex flex-col gap-0.5", children: [
1234
- /* @__PURE__ */ jsx18(BaseMenu.GroupLabel, { render: heading }),
1257
+ return /* @__PURE__ */ jsxs12(BaseMenu.Group, { className: "flex flex-col gap-0.5", children: [
1258
+ /* @__PURE__ */ jsx19(BaseMenu.GroupLabel, { render: heading }),
1235
1259
  children
1236
1260
  ] });
1237
1261
  }
1238
1262
  function MenuSeparator() {
1239
- return /* @__PURE__ */ jsx18(Divider, { className: "my-1" });
1263
+ return /* @__PURE__ */ jsx19(Divider, { className: "my-1" });
1240
1264
  }
1241
1265
  function MenuRow({ children, className }) {
1242
- return /* @__PURE__ */ jsx18("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
1266
+ return /* @__PURE__ */ jsx19("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
1243
1267
  }
1244
1268
 
1245
- // src/BlockHandle.tsx
1246
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1247
- function readId(element) {
1248
- const own = element.getAttribute("data-block-id") ?? element.querySelector("[data-block-id]")?.getAttribute("data-block-id");
1249
- return own || void 0;
1250
- }
1251
- function blockAtY(blocks, y) {
1252
- let found = null;
1253
- for (const block of blocks) {
1254
- if (block.element.getBoundingClientRect().top > y) break;
1255
- found = block;
1256
- }
1257
- return found ?? blocks[0] ?? null;
1258
- }
1259
- function readingBlocks(root) {
1260
- if (!root) return [];
1261
- return Array.from(root.children).filter((el) => el instanceof HTMLElement).map((element) => ({ id: readId(element), element })).filter((b) => b.id !== void 0);
1262
- }
1263
- var HANDLE = 24;
1264
- function firstLineOffset(element) {
1265
- const text = element.querySelector("p, h1, h2, h3, pre, li") ?? element;
1266
- const line = parseFloat(getComputedStyle(text).lineHeight);
1267
- if (!Number.isFinite(line)) return 0;
1268
- const inset = text === element ? 0 : text.getBoundingClientRect().top - element.getBoundingClientRect().top;
1269
- return inset + (line - HANDLE) / 2;
1269
+ // src/ChipInput.tsx
1270
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1271
+ var CHIP_BOX = (
1272
+ // Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
1273
+ // rounded-sm corners — never a forced circle — and the chip's corner
1274
+ // follows concentrically: 4px face + 2px inset = rounded-md.
1275
+ "inline-flex items-center gap-1.5 bg-bg-elevated border border-border-subtle rounded-md py-0.5 max-h-[24px]"
1276
+ );
1277
+ var CHIP_LABEL = "text-caption font-medium text-text-primary";
1278
+ var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
1279
+ var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
1280
+ function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
1281
+ return /* @__PURE__ */ jsxs13("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
1282
+ leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: leading }),
1283
+ /* @__PURE__ */ jsx20("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
1284
+ onRemove && /* @__PURE__ */ jsx20(
1285
+ BaseButton4,
1286
+ {
1287
+ type: "button",
1288
+ onClick: (e) => {
1289
+ e.stopPropagation();
1290
+ onRemove();
1291
+ },
1292
+ className: cn(CHIP_REMOVE, truncate && "shrink-0"),
1293
+ "aria-label": removeLabel ?? `Remove ${label}`,
1294
+ children: /* @__PURE__ */ jsx20(IconX3, { size: 10, stroke: 1.5 })
1295
+ }
1296
+ )
1297
+ ] });
1270
1298
  }
1271
- function BlockHandle({ actions, editing, children, className }) {
1272
- const frame = useRef3(null);
1273
- const content = useRef3(null);
1274
- const [block, setBlock] = useState2(null);
1275
- const [top, setTop] = useState2(0);
1276
- const [open, setOpen] = useState2(false);
1277
- const follow = useCallback(
1278
- (y) => {
1279
- if (!content.current || !frame.current) return;
1280
- const found = editing ? editing.find(y) : blockAtY(readingBlocks(content.current.firstElementChild), y);
1281
- setBlock(found);
1282
- if (found) setTop(found.element.getBoundingClientRect().top - frame.current.getBoundingClientRect().top + firstLineOffset(found.element));
1299
+ function ChipInput({
1300
+ value,
1301
+ onChange,
1302
+ options,
1303
+ placeholder = "Search\u2026",
1304
+ autoFocus,
1305
+ excludeIds = [],
1306
+ chipLeading,
1307
+ rowLeading,
1308
+ ...aria
1309
+ }) {
1310
+ const [query, setQuery] = useState2("");
1311
+ const [box, setBox] = useState2(null);
1312
+ const available = useMemo(() => {
1313
+ const chosen = new Set(value.map((o) => o.id));
1314
+ const excluded = new Set(excludeIds);
1315
+ return options.filter((o) => !chosen.has(o.id) && !excluded.has(o.id));
1316
+ }, [options, value, excludeIds]);
1317
+ const filter = useMemo(
1318
+ () => (item, q) => {
1319
+ const needle = q.trim().toLowerCase();
1320
+ if (!needle) return true;
1321
+ return item.label.toLowerCase().includes(needle) || (item.description ?? "").toLowerCase().includes(needle);
1283
1322
  },
1284
- [editing]
1323
+ []
1285
1324
  );
1286
- useEffect2(() => {
1287
- if (!editing) return;
1288
- return editing.onChange(() => {
1289
- if (!open) setBlock(null);
1290
- });
1291
- }, [editing, open]);
1292
- const rows = editing && block ? editing.rows(block) : null;
1293
- const own = actions && block ? actions(block) : null;
1294
- const dragging = useRef3(false);
1295
- const [line, setLine] = useState2(null);
1296
- const inGutter = (e) => dragging.current && !!editing && !!content.current && !content.current.contains(e.target);
1297
- const landing = (y) => {
1298
- const target = editing?.find(y);
1299
- if (!target || !frame.current) return null;
1300
- const box = target.element.getBoundingClientRect();
1301
- const after = y > box.top + box.height / 2;
1302
- const neighbour = (after ? target.element.nextElementSibling : target.element.previousElementSibling)?.getBoundingClientRect();
1303
- const edge = after ? neighbour ? (box.bottom + neighbour.top) / 2 : box.bottom : neighbour ? (neighbour.bottom + box.top) / 2 : box.top;
1304
- return { target, after, top: edge - frame.current.getBoundingClientRect().top };
1305
- };
1306
- const endDrag = () => {
1307
- dragging.current = false;
1308
- setLine(null);
1309
- editing?.endDrag();
1325
+ const open = query.trim().length > 0;
1326
+ const ariaLabel = aria["aria-label"] ?? (value.length > 0 ? placeholder : void 0);
1327
+ const naming = {
1328
+ ...ariaLabel !== void 0 && { "aria-label": ariaLabel },
1329
+ ...aria["aria-labelledby"] !== void 0 && { "aria-labelledby": aria["aria-labelledby"] }
1310
1330
  };
1311
- return /* @__PURE__ */ jsxs12(
1312
- "div",
1331
+ function removeLast() {
1332
+ if (value.length > 0) onChange(value.slice(0, -1));
1333
+ }
1334
+ function onInputKeyDown(event) {
1335
+ if (event.key === "Backspace" && query === "" && value.length > 0) {
1336
+ event.preventDefault();
1337
+ event.stopPropagation();
1338
+ removeLast();
1339
+ return;
1340
+ }
1341
+ if (event.key === "Escape" && query !== "") {
1342
+ event.preventDefault();
1343
+ event.stopPropagation();
1344
+ setQuery("");
1345
+ }
1346
+ }
1347
+ return /* @__PURE__ */ jsxs13(
1348
+ Combobox.Root,
1313
1349
  {
1314
- ref: frame,
1315
- className: cn("relative", className),
1316
- onMouseMove: (e) => {
1317
- if (!open) follow(e.clientY);
1318
- },
1319
- onMouseLeave: () => {
1320
- if (!open) setBlock(null);
1321
- },
1322
- onDragOver: (e) => {
1323
- if (!inGutter(e)) return setLine(null);
1324
- e.preventDefault();
1325
- setLine(landing(e.clientY)?.top ?? null);
1326
- },
1327
- onDrop: (e) => {
1328
- if (inGutter(e)) {
1329
- e.preventDefault();
1330
- const at = landing(e.clientY);
1331
- if (at) editing?.drop(at.target, at.after);
1332
- }
1333
- endDrag();
1334
- },
1335
- onDragLeave: (e) => {
1336
- if (!frame.current?.contains(e.relatedTarget)) setLine(null);
1350
+ multiple: true,
1351
+ items: available,
1352
+ value,
1353
+ onValueChange: (next) => {
1354
+ onChange(next);
1355
+ setQuery("");
1337
1356
  },
1357
+ inputValue: query,
1358
+ onInputValueChange: setQuery,
1359
+ open,
1360
+ openOnInputClick: false,
1361
+ filter,
1362
+ itemToStringLabel: (option) => option.label,
1338
1363
  children: [
1339
- /* @__PURE__ */ jsx19("div", { ref: content, children }),
1340
- /* @__PURE__ */ jsx19("div", { "aria-hidden": true, className: "absolute inset-y-0 -left-7 w-7" }),
1341
- line !== null && /* @__PURE__ */ jsx19("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-x-0 h-px bg-accent-primary", style: { top: line } }),
1342
- block && (rows || own) && // The top is the block's, measured: it depends on the document, not on a size of ours.
1343
- /* @__PURE__ */ jsx19("div", { className: cn("absolute -left-7", rows && "cursor-grab active:cursor-grabbing"), style: { top }, children: /* @__PURE__ */ jsxs12(
1344
- Menu,
1364
+ /* @__PURE__ */ jsxs13(Combobox.Chips, { ref: setBox, className: cn(FIELD_SHELL_CLASSES, "focus-within:border-border-focus focus-within:hover:border-border-focus group-hover/field:focus-within:border-border-focus px-3 py-1.5 flex flex-wrap items-center gap-1.5 min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring"), children: [
1365
+ value.map((option) => /* @__PURE__ */ jsxs13(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
1366
+ chipLeading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
1367
+ /* @__PURE__ */ jsx20("span", { className: CHIP_LABEL, children: option.label }),
1368
+ /* @__PURE__ */ jsx20(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx20(IconX3, { size: 10, stroke: 1.5 }) })
1369
+ ] }, option.id)),
1370
+ /* @__PURE__ */ jsx20(
1371
+ Combobox.Input,
1372
+ {
1373
+ autoFocus,
1374
+ placeholder: value.length === 0 ? placeholder : "",
1375
+ "aria-required": aria["aria-required"],
1376
+ ...naming,
1377
+ onKeyDown: onInputKeyDown,
1378
+ className: cn("flex-1 min-w-[120px] text-body-2 border-none", BARE_INPUT_CLASSES)
1379
+ }
1380
+ )
1381
+ ] }),
1382
+ /* @__PURE__ */ jsx20(Combobox.Portal, { children: /* @__PURE__ */ jsx20(
1383
+ Combobox.Positioner,
1345
1384
  {
1346
- open,
1347
- onOpenChange: setOpen,
1348
- trigger: /* @__PURE__ */ jsx19(
1349
- IconButton,
1385
+ anchor: box,
1386
+ sideOffset: GAP3,
1387
+ collisionPadding: VIEWPORT_PAD3,
1388
+ className: "z-50 data-[anchor-hidden]:hidden",
1389
+ 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, { className: "flex flex-col gap-0.5", children: (option) => /* @__PURE__ */ jsx20(
1390
+ Combobox.Item,
1350
1391
  {
1351
- "aria-label": "Block menu",
1352
- tooltip: rows ? "Drag to move, click for the menu" : "Menu",
1353
- draggable: !!rows,
1354
- onMouseDown: (e) => e.preventBaseUIHandler(),
1355
- onClick: (e) => {
1356
- e.preventBaseUIHandler();
1357
- setOpen((was) => !was);
1358
- },
1359
- onDragStart: (e) => {
1360
- if (!editing || !rows) return;
1361
- setOpen(false);
1362
- dragging.current = true;
1363
- editing.startDrag(block, e.nativeEvent);
1364
- },
1365
- onDragEnd: () => {
1366
- endDrag();
1367
- setBlock(null);
1368
- },
1369
- children: /* @__PURE__ */ jsx19(IconGripVertical, { size: 16, stroke: 1.5 })
1370
- }
1371
- ),
1372
- children: [
1373
- rows,
1374
- rows && own && /* @__PURE__ */ jsx19(MenuSeparator, {}),
1375
- own
1376
- ]
1377
- }
1378
- ) })
1392
+ value: option,
1393
+ render: /* @__PURE__ */ jsx20(
1394
+ MenuItem,
1395
+ {
1396
+ size: "tall",
1397
+ leading: rowLeading?.(option),
1398
+ label: option.label,
1399
+ description: option.description
1400
+ }
1401
+ )
1402
+ },
1403
+ option.id
1404
+ ) }) }) })
1405
+ }
1406
+ ) })
1407
+ ]
1408
+ }
1409
+ );
1410
+ }
1411
+ var GAP3 = 4;
1412
+ var VIEWPORT_PAD3 = 8;
1413
+
1414
+ // src/DialogShell.tsx
1415
+ import { useRef as useRef3 } from "react";
1416
+ import { Dialog as Dialog2 } from "@base-ui/react/dialog";
1417
+ import { AlertDialog } from "@base-ui/react/alert-dialog";
1418
+ import { IconX as IconX4 } from "@tabler/icons-react";
1419
+
1420
+ // src/ContainerHeader.tsx
1421
+ import { IconChevronDown } from "@tabler/icons-react";
1422
+ import { Button as BaseButton5 } from "@base-ui/react/button";
1423
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1424
+ function ContainerHeader({ title, chevron = false, titleMenu, actions, className }) {
1425
+ const text = typeof title === "string";
1426
+ const name = /* @__PURE__ */ jsxs14("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
1427
+ text ? /* @__PURE__ */ jsx21("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx21("div", { className: "min-w-0 flex-1", children: title }),
1428
+ (chevron || titleMenu != null) && /* @__PURE__ */ jsx21(IconChevronDown, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1429
+ ] });
1430
+ return (
1431
+ // The title 16px in, where the column's content starts (Katerina, 7 October; it was 20px).
1432
+ // With a title menu the bar gives the button 6px of its left padding
1433
+ // (pl-2.5 + the button's px-1.5 = pl-4): the words stay where a title's
1434
+ // are, and the fill is inside the bar — a negative margin had it clipped
1435
+ // (Katerina, 5 October).
1436
+ /* @__PURE__ */ jsxs14("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4", titleMenu != null ? "pl-2.5" : "pl-4", className), children: [
1437
+ /* @__PURE__ */ jsx21("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: titleMenu != null ? /* @__PURE__ */ jsx21(
1438
+ Menu,
1439
+ {
1440
+ trigger: /* @__PURE__ */ jsx21(BaseButton5, { type: "button", className: cn("flex min-w-0 items-center px-1.5 py-1", MENU_TRIGGER_CLASSES), children: name }),
1441
+ children: titleMenu
1442
+ }
1443
+ ) : name }),
1444
+ actions && /* @__PURE__ */ jsx21("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx21("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
1445
+ ] })
1446
+ );
1447
+ }
1448
+
1449
+ // src/DialogShell.tsx
1450
+ import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1451
+ function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
1452
+ const Parts = alert ? AlertDialog : Dialog2;
1453
+ const popupRef = useRef3(null);
1454
+ return /* @__PURE__ */ jsx22(
1455
+ Parts.Root,
1456
+ {
1457
+ open: true,
1458
+ onOpenChange: (open) => {
1459
+ if (!open) onClose();
1460
+ },
1461
+ children: /* @__PURE__ */ jsxs15(Parts.Portal, { children: [
1462
+ /* @__PURE__ */ jsx22(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1463
+ /* @__PURE__ */ jsx22("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs15(
1464
+ Parts.Popup,
1465
+ {
1466
+ ref: popupRef,
1467
+ initialFocus: popupRef,
1468
+ "aria-label": headerContent != null ? title : void 0,
1469
+ className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
1470
+ style: { width },
1471
+ children: [
1472
+ /* @__PURE__ */ jsx22(
1473
+ ContainerHeader,
1474
+ {
1475
+ className: "pl-5",
1476
+ title: headerContent ?? /* @__PURE__ */ jsx22(Parts.Title, { className: "block truncate text-h4 text-text-primary", render: /* @__PURE__ */ jsx22("span", {}), children: title }),
1477
+ actions: (
1478
+ /*
1479
+ The ✕ IS the `Close` part now, rather than a button that calls
1480
+ `onClose` beside one (stage 4, 2026-09-07). Stage 3 could not do
1481
+ this: an `IconButton` carrying a `tooltip` returned the tooltip
1482
+ wrapper `<div>` as its root, so the part composed onto the
1483
+ wrapper and not the button. Porting Tooltip removed the wrapper
1484
+ — the trigger is the button itself — and the composition works.
1485
+
1486
+ What it buys: the dialog closes through its own state machine,
1487
+ so the ✕, Escape and the outside press are one path with one
1488
+ reason attached, instead of one of the three going around.
1489
+ */
1490
+ /* @__PURE__ */ jsx22(
1491
+ Parts.Close,
1492
+ {
1493
+ render: /* @__PURE__ */ jsx22(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx22(IconX4, { size: 16, stroke: 1.5 }) })
1494
+ }
1495
+ )
1496
+ )
1497
+ }
1498
+ ),
1499
+ bodyMaxHeight ? (
1500
+ // The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
1501
+ /* @__PURE__ */ jsx22("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx22(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
1502
+ ) : /* @__PURE__ */ jsx22("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1503
+ footer != null && /* @__PURE__ */ jsx22("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
1504
+ ]
1505
+ }
1506
+ ) })
1507
+ ] })
1508
+ }
1509
+ );
1510
+ }
1511
+
1512
+ // src/Field.tsx
1513
+ import { cloneElement, isValidElement } from "react";
1514
+ import { Field as BaseField } from "@base-ui/react/field";
1515
+ import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1516
+ var LINE_STYLES = {
1517
+ helper: "text-caption text-text-muted",
1518
+ warning: "text-caption text-warning-default",
1519
+ error: "text-caption text-error-default"
1520
+ };
1521
+ function Field({ label, required = false, helper, error, children }) {
1522
+ const control = required && isValidElement(children) ? cloneElement(children, {
1523
+ "aria-required": children.props["aria-required"] ?? true
1524
+ }) : children;
1525
+ return (
1526
+ // `group/field`: the label, the box and the line under it are one thing under the pointer —
1527
+ // anywhere in it strengthens the box's border, as hovering the box does (Katerina, 28 September).
1528
+ // Before, the 8px between the label and the box was a gap where the border went out again.
1529
+ /* @__PURE__ */ jsxs16(BaseField.Root, { invalid: !!error, className: "group/field flex flex-col gap-2", children: [
1530
+ /* @__PURE__ */ jsxs16(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1531
+ label,
1532
+ required && /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1533
+ ] }),
1534
+ /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
1535
+ control,
1536
+ error != null ? /* @__PURE__ */ jsx23(BaseField.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx23(BaseField.Description, { className: LINE_STYLES.helper, children: helper }) : null
1537
+ ] })
1538
+ ] })
1539
+ );
1540
+ }
1541
+ function FieldLine({ tone = "helper", children, className }) {
1542
+ return /* @__PURE__ */ jsx23("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1543
+ }
1544
+
1545
+ // src/Form.tsx
1546
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef4 } from "react";
1547
+ import { Fieldset } from "@base-ui/react/fieldset";
1548
+ import { Form as BaseForm } from "@base-ui/react/form";
1549
+ import { jsx as jsx24 } from "react/jsx-runtime";
1550
+ var FIELDS_CLASSES = "flex flex-col gap-6";
1551
+ var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
1552
+ var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1553
+ function usable(element) {
1554
+ return element instanceof HTMLElement && element.isConnected && element.matches(CONTROL) && !element.matches(":disabled") && element.getAttribute("aria-disabled") !== "true";
1555
+ }
1556
+ function firstInvalid(form) {
1557
+ for (const marked of form.querySelectorAll("[data-invalid]")) {
1558
+ if (usable(marked)) return marked;
1559
+ const inside = Array.from(marked.querySelectorAll(CONTROL)).find(usable);
1560
+ if (inside) return inside;
1561
+ }
1562
+ return void 0;
1563
+ }
1564
+ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fields", className, children, ...props }) {
1565
+ const outerBusy = useFormBusy();
1566
+ const busy = ownBusy || outerBusy;
1567
+ const form = useRef4(null);
1568
+ const busyNow = useRef4(busy);
1569
+ busyNow.current = busy;
1570
+ const sender = useRef4(null);
1571
+ const holding = useRef4(false);
1572
+ const lastInside = useRef4(null);
1573
+ useLayoutEffect2(() => {
1574
+ const element = form.current;
1575
+ if (!element) return;
1576
+ if (busy) {
1577
+ const active = document.activeElement;
1578
+ const from = active && active !== element && element.contains(active) ? active : !active || active === document.body ? lastInside.current : null;
1579
+ if (from?.isConnected) {
1580
+ sender.current = from;
1581
+ holding.current = true;
1582
+ element.focus();
1583
+ }
1584
+ return;
1585
+ }
1586
+ if (!holding.current) return;
1587
+ holding.current = false;
1588
+ if (document.activeElement !== element && document.activeElement !== document.body) return;
1589
+ const target = firstInvalid(element) ?? (usable(sender.current) ? sender.current : Array.from(element.querySelectorAll(CONTROL)).find(usable));
1590
+ sender.current = null;
1591
+ target?.focus();
1592
+ }, [busy]);
1593
+ const onKeyDown = (event) => {
1594
+ props.onKeyDown?.(event);
1595
+ if (event.key !== "Enter" || event.defaultPrevented || event.nativeEvent.isComposing) return;
1596
+ const target = event.target;
1597
+ const inInput = target instanceof HTMLInputElement;
1598
+ if (inInput) event.preventDefault();
1599
+ if (event.altKey || event.shiftKey) return;
1600
+ if (event.ctrlKey || event.metaKey) {
1601
+ event.preventDefault();
1602
+ form.current?.requestSubmit();
1603
+ return;
1604
+ }
1605
+ if (!inInput) return;
1606
+ const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
1607
+ if (enterSends && oneLine) form.current?.requestSubmit();
1608
+ };
1609
+ return /* @__PURE__ */ jsx24(
1610
+ BaseForm,
1611
+ {
1612
+ ref: form,
1613
+ ...props,
1614
+ tabIndex: busy ? -1 : props.tabIndex,
1615
+ className: cn("outline-none", layout === "fields" && FIELDS_CLASSES, className),
1616
+ onFocus: (event) => {
1617
+ if (event.target !== form.current) lastInside.current = event.target;
1618
+ props.onFocus?.(event);
1619
+ },
1620
+ onBlur: (event) => {
1621
+ const next = event.relatedTarget;
1622
+ if (next && !form.current?.contains(next)) lastInside.current = null;
1623
+ props.onBlur?.(event);
1624
+ },
1625
+ onKeyDown,
1626
+ onSubmit: (event) => {
1627
+ if (event.target !== event.currentTarget) return;
1628
+ event.preventDefault();
1629
+ if (busyNow.current) return;
1630
+ void onSubmit();
1631
+ },
1632
+ children: /* @__PURE__ */ jsx24(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx24(FormBusyContext.Provider, { value: busy, children }) })
1633
+ }
1634
+ );
1635
+ }
1636
+
1637
+ // src/MembersDialog.tsx
1638
+ import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1639
+ var LEADING_CLASSES = "size-8 rounded-md bg-accent-muted flex items-center justify-center shrink-0 text-accent-primary";
1640
+ function MembersDialog({ members, count, self, candidates = [], onAdd, note, initialView = "list", onClose }) {
1641
+ const [view, setView] = useState3(onAdd ? initialView : "list");
1642
+ const [chosen, setChosen] = useState3([]);
1643
+ const [toggling, setToggling] = useState3(false);
1644
+ const formId = useId();
1645
+ const toggle = async () => {
1646
+ if (!self || toggling) return;
1647
+ setToggling(true);
1648
+ try {
1649
+ await self.onToggle();
1650
+ } finally {
1651
+ setToggling(false);
1652
+ }
1653
+ };
1654
+ const add = async () => {
1655
+ if (!onAdd || chosen.length === 0) return;
1656
+ if (await onAdd(chosen) === false) return;
1657
+ setChosen([]);
1658
+ setView("list");
1659
+ };
1660
+ if (view === "add" && onAdd) {
1661
+ return /* @__PURE__ */ jsx25(
1662
+ DialogShell,
1663
+ {
1664
+ title: "Add members",
1665
+ onClose,
1666
+ headerContent: /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 items-center gap-2", children: [
1667
+ /* @__PURE__ */ jsx25(IconButton, { tooltip: "Back to members", "aria-label": "Back to members", className: "-ml-2", onClick: () => setView("list"), children: /* @__PURE__ */ jsx25(IconArrowLeft, { size: 16, stroke: 1.5 }) }),
1668
+ /* @__PURE__ */ jsx25("span", { className: "truncate text-h4 text-text-primary", children: "Add members" })
1669
+ ] }),
1670
+ bodyClassName: "flex flex-col gap-6",
1671
+ footer: /* @__PURE__ */ jsxs17(Fragment5, { children: [
1672
+ /* @__PURE__ */ jsx25(Button, { variant: "muted", onClick: onClose, children: "Cancel" }),
1673
+ /* @__PURE__ */ jsx25(Button, { variant: "primary", type: "submit", form: formId, disabled: chosen.length === 0, children: "Invite" })
1674
+ ] }),
1675
+ children: /* @__PURE__ */ jsx25(Form, { id: formId, onSubmit: add, children: /* @__PURE__ */ jsx25(Field, { label: "Invite people", required: true, children: /* @__PURE__ */ jsx25(
1676
+ ChipInput,
1677
+ {
1678
+ value: chosen,
1679
+ onChange: setChosen,
1680
+ options: candidates,
1681
+ placeholder: "Search people...",
1682
+ excludeIds: members.map((m) => m.id),
1683
+ chipLeading: (o) => /* @__PURE__ */ jsx25(Avatar, { name: o.label, src: o.picture, size: 16 }),
1684
+ rowLeading: (o) => /* @__PURE__ */ jsx25(Avatar, { name: o.label, src: o.picture, size: 32 }),
1685
+ autoFocus: true
1686
+ }
1687
+ ) }) })
1688
+ }
1689
+ );
1690
+ }
1691
+ return /* @__PURE__ */ jsxs17(
1692
+ DialogShell,
1693
+ {
1694
+ title: "Members",
1695
+ onClose,
1696
+ headerContent: /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 items-center gap-2", children: [
1697
+ /* @__PURE__ */ jsx25("span", { className: "truncate text-h4 text-text-primary", children: "Members" }),
1698
+ /* @__PURE__ */ jsx25(Chip, { label: String(count ?? members.length) })
1699
+ ] }),
1700
+ bodyMaxHeight: "max-h-[400px]",
1701
+ bodyClassName: "p-0 py-2",
1702
+ children: [
1703
+ (self || onAdd) && /* @__PURE__ */ jsxs17("div", { className: "flex flex-col px-2", children: [
1704
+ self && /* @__PURE__ */ jsx25(
1705
+ MenuItem,
1706
+ {
1707
+ size: "tall",
1708
+ className: "py-2",
1709
+ disabled: toggling,
1710
+ onClick: () => void toggle(),
1711
+ leading: /* @__PURE__ */ jsx25("span", { className: LEADING_CLASSES, children: self.action === "join" ? /* @__PURE__ */ jsx25(IconUserPlus, { size: 16, stroke: 1.5 }) : /* @__PURE__ */ jsx25(IconUserMinus, { size: 16, stroke: 1.5 }) }),
1712
+ label: self.action === "join" ? "Join" : "Leave"
1713
+ }
1714
+ ),
1715
+ onAdd && /* @__PURE__ */ jsx25(
1716
+ MenuItem,
1717
+ {
1718
+ size: "tall",
1719
+ className: "py-2",
1720
+ onClick: () => setView("add"),
1721
+ leading: /* @__PURE__ */ jsx25("span", { className: LEADING_CLASSES, children: /* @__PURE__ */ jsx25(IconUserPlus, { size: 16, stroke: 1.5 }) }),
1722
+ label: "Add members"
1723
+ }
1724
+ )
1725
+ ] }),
1726
+ members.map((member) => /* @__PURE__ */ jsxs17("div", { className: "flex h-12 items-center gap-3 px-5", children: [
1727
+ /* @__PURE__ */ jsx25(Avatar, { size: 32, name: member.name, src: member.picture }),
1728
+ /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-[2px]", children: [
1729
+ /* @__PURE__ */ jsx25("div", { className: "truncate text-body-2 text-text-primary", children: member.name }),
1730
+ member.caption && /* @__PURE__ */ jsx25("div", { className: "truncate text-caption text-text-secondary", children: member.caption })
1731
+ ] })
1732
+ ] }, member.id)),
1733
+ note && /* @__PURE__ */ jsx25("div", { className: "px-5 pb-2 pt-3 text-caption text-text-secondary", children: note })
1734
+ ]
1735
+ }
1736
+ );
1737
+ }
1738
+
1739
+ // src/Banner.tsx
1740
+ import { IconX as IconX5 } from "@tabler/icons-react";
1741
+ import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
1742
+ var TONE_STYLES = {
1743
+ ok: "bg-success-muted text-success-default",
1744
+ error: "bg-error-muted text-error-default",
1745
+ info: "bg-info-muted text-info-default",
1746
+ warning: "bg-warning-muted text-warning-default"
1747
+ };
1748
+ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismiss", className }) {
1749
+ const role = tone === "error" ? "alert" : "status";
1750
+ if (!onDismiss && !icon && !action) {
1751
+ return /* @__PURE__ */ jsx26("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
1752
+ }
1753
+ const oneLine = Boolean(icon || action);
1754
+ return /* @__PURE__ */ jsxs18("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
1755
+ icon && /* @__PURE__ */ jsx26("span", { className: "flex shrink-0", children: icon }),
1756
+ /* @__PURE__ */ jsx26("span", { className: cn("min-w-0 flex-1", oneLine && "truncate"), children }),
1757
+ action && /* @__PURE__ */ jsx26(Button, { variant: "muted", size: "small", className: "shrink-0", onClick: action.onClick, children: action.label }),
1758
+ onDismiss && /* @__PURE__ */ jsx26(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx26(IconX5, { size: 16, stroke: 1.5 }) })
1759
+ ] });
1760
+ }
1761
+
1762
+ // src/BlockHandle.tsx
1763
+ import { useCallback, useEffect as useEffect2, useRef as useRef5, useState as useState4 } from "react";
1764
+ import { IconGripVertical } from "@tabler/icons-react";
1765
+ import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
1766
+ function readId(element) {
1767
+ const own = element.getAttribute("data-block-id") ?? element.querySelector("[data-block-id]")?.getAttribute("data-block-id");
1768
+ return own || void 0;
1769
+ }
1770
+ function blockAtY(blocks, y) {
1771
+ let found = null;
1772
+ for (const block of blocks) {
1773
+ if (block.element.getBoundingClientRect().top > y) break;
1774
+ found = block;
1775
+ }
1776
+ return found ?? blocks[0] ?? null;
1777
+ }
1778
+ function readingBlocks(root) {
1779
+ if (!root) return [];
1780
+ return Array.from(root.children).filter((el) => el instanceof HTMLElement).map((element) => ({ id: readId(element), element })).filter((b) => b.id !== void 0);
1781
+ }
1782
+ var HANDLE = 24;
1783
+ function firstLineOffset(element) {
1784
+ const text = element.querySelector("p, h1, h2, h3, pre, li") ?? element;
1785
+ const line = parseFloat(getComputedStyle(text).lineHeight);
1786
+ if (!Number.isFinite(line)) return 0;
1787
+ const inset = text === element ? 0 : text.getBoundingClientRect().top - element.getBoundingClientRect().top;
1788
+ return inset + (line - HANDLE) / 2;
1789
+ }
1790
+ function BlockHandle({ actions, editing, children, className }) {
1791
+ const frame = useRef5(null);
1792
+ const content = useRef5(null);
1793
+ const [block, setBlock] = useState4(null);
1794
+ const [top, setTop] = useState4(0);
1795
+ const [open, setOpen] = useState4(false);
1796
+ const follow = useCallback(
1797
+ (y) => {
1798
+ if (!content.current || !frame.current) return;
1799
+ const found = editing ? editing.find(y) : blockAtY(readingBlocks(content.current.firstElementChild), y);
1800
+ setBlock(found);
1801
+ if (found) setTop(found.element.getBoundingClientRect().top - frame.current.getBoundingClientRect().top + firstLineOffset(found.element));
1802
+ },
1803
+ [editing]
1804
+ );
1805
+ useEffect2(() => {
1806
+ if (!editing) return;
1807
+ return editing.onChange(() => {
1808
+ if (!open) setBlock(null);
1809
+ });
1810
+ }, [editing, open]);
1811
+ const rows = editing && block ? editing.rows(block) : null;
1812
+ const own = actions && block ? actions(block) : null;
1813
+ const dragging = useRef5(false);
1814
+ const [line, setLine] = useState4(null);
1815
+ const inGutter = (e) => dragging.current && !!editing && !!content.current && !content.current.contains(e.target);
1816
+ const landing = (y) => {
1817
+ const target = editing?.find(y);
1818
+ if (!target || !frame.current) return null;
1819
+ const box = target.element.getBoundingClientRect();
1820
+ const after = y > box.top + box.height / 2;
1821
+ const neighbour = (after ? target.element.nextElementSibling : target.element.previousElementSibling)?.getBoundingClientRect();
1822
+ const edge = after ? neighbour ? (box.bottom + neighbour.top) / 2 : box.bottom : neighbour ? (neighbour.bottom + box.top) / 2 : box.top;
1823
+ return { target, after, top: edge - frame.current.getBoundingClientRect().top };
1824
+ };
1825
+ const endDrag = () => {
1826
+ dragging.current = false;
1827
+ setLine(null);
1828
+ editing?.endDrag();
1829
+ };
1830
+ return /* @__PURE__ */ jsxs19(
1831
+ "div",
1832
+ {
1833
+ ref: frame,
1834
+ className: cn("relative", className),
1835
+ onMouseMove: (e) => {
1836
+ if (!open) follow(e.clientY);
1837
+ },
1838
+ onMouseLeave: () => {
1839
+ if (!open) setBlock(null);
1840
+ },
1841
+ onDragOver: (e) => {
1842
+ if (!inGutter(e)) return setLine(null);
1843
+ e.preventDefault();
1844
+ setLine(landing(e.clientY)?.top ?? null);
1845
+ },
1846
+ onDrop: (e) => {
1847
+ if (inGutter(e)) {
1848
+ e.preventDefault();
1849
+ const at = landing(e.clientY);
1850
+ if (at) editing?.drop(at.target, at.after);
1851
+ }
1852
+ endDrag();
1853
+ },
1854
+ onDragLeave: (e) => {
1855
+ if (!frame.current?.contains(e.relatedTarget)) setLine(null);
1856
+ },
1857
+ children: [
1858
+ /* @__PURE__ */ jsx27("div", { ref: content, children }),
1859
+ /* @__PURE__ */ jsx27("div", { "aria-hidden": true, className: "absolute inset-y-0 -left-7 w-7" }),
1860
+ line !== null && /* @__PURE__ */ jsx27("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-x-0 h-px bg-accent-primary", style: { top: line } }),
1861
+ block && (rows || own) && // The top is the block's, measured: it depends on the document, not on a size of ours.
1862
+ /* @__PURE__ */ jsx27("div", { className: cn("absolute -left-7", rows && "cursor-grab active:cursor-grabbing"), style: { top }, children: /* @__PURE__ */ jsxs19(
1863
+ Menu,
1864
+ {
1865
+ open,
1866
+ onOpenChange: setOpen,
1867
+ trigger: /* @__PURE__ */ jsx27(
1868
+ IconButton,
1869
+ {
1870
+ "aria-label": "Block menu",
1871
+ tooltip: rows ? "Drag to move, click for the menu" : "Menu",
1872
+ draggable: !!rows,
1873
+ onMouseDown: (e) => e.preventBaseUIHandler(),
1874
+ onClick: (e) => {
1875
+ e.preventBaseUIHandler();
1876
+ setOpen((was) => !was);
1877
+ },
1878
+ onDragStart: (e) => {
1879
+ if (!editing || !rows) return;
1880
+ setOpen(false);
1881
+ dragging.current = true;
1882
+ editing.startDrag(block, e.nativeEvent);
1883
+ },
1884
+ onDragEnd: () => {
1885
+ endDrag();
1886
+ setBlock(null);
1887
+ },
1888
+ children: /* @__PURE__ */ jsx27(IconGripVertical, { size: 16, stroke: 1.5 })
1889
+ }
1890
+ ),
1891
+ children: [
1892
+ rows,
1893
+ rows && own && /* @__PURE__ */ jsx27(MenuSeparator, {}),
1894
+ own
1895
+ ]
1896
+ }
1897
+ ) })
1379
1898
  ]
1380
1899
  }
1381
1900
  );
@@ -1383,9 +1902,9 @@ function BlockHandle({ actions, editing, children, className }) {
1383
1902
 
1384
1903
  // src/Checkbox.tsx
1385
1904
  import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
1386
- import { Field as BaseField } from "@base-ui/react/field";
1905
+ import { Field as BaseField2 } from "@base-ui/react/field";
1387
1906
  import { IconCheck } from "@tabler/icons-react";
1388
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1907
+ import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
1389
1908
  function squareClasses(checked, disabled, interactive, className) {
1390
1909
  return cn(
1391
1910
  "inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
@@ -1402,14 +1921,14 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
1402
1921
  const formBusy = useFormBusy();
1403
1922
  const disabled = ownDisabled || formBusy;
1404
1923
  if (!onChange) {
1405
- const picture = /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx20("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx20(IconCheck, { size: 12, stroke: 3 }) }) });
1924
+ const picture = /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx28("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx28(IconCheck, { size: 12, stroke: 3 }) }) });
1406
1925
  if (label === void 0) return picture;
1407
- return /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2", children: [
1926
+ return /* @__PURE__ */ jsxs20("span", { className: "flex items-center gap-2", children: [
1408
1927
  picture,
1409
- /* @__PURE__ */ jsx20("span", { className: WORDS_CLASSES, children: label })
1928
+ /* @__PURE__ */ jsx28("span", { className: WORDS_CLASSES, children: label })
1410
1929
  ] });
1411
1930
  }
1412
- const box = /* @__PURE__ */ jsx20(
1931
+ const box = /* @__PURE__ */ jsx28(
1413
1932
  BaseCheckbox.Root,
1414
1933
  {
1415
1934
  checked,
@@ -1419,372 +1938,69 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
1419
1938
  onCheckedChange: (next) => onChange(next),
1420
1939
  onClick: (e) => e.stopPropagation(),
1421
1940
  className: (state) => squareClasses(state.checked, state.disabled, true, className),
1422
- children: /* @__PURE__ */ jsx20(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx20(IconCheck, { size: 12, stroke: 3 }) })
1941
+ children: /* @__PURE__ */ jsx28(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx28(IconCheck, { size: 12, stroke: 3 }) })
1423
1942
  }
1424
1943
  );
1425
1944
  if (label === void 0) return box;
1426
1945
  if (row) {
1427
- return /* @__PURE__ */ jsx20(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs13(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
1946
+ return /* @__PURE__ */ jsx28(BaseField2.Root, { disabled, children: /* @__PURE__ */ jsxs20(BaseField2.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
1428
1947
  leading,
1429
- /* @__PURE__ */ jsx20("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
1948
+ /* @__PURE__ */ jsx28("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
1430
1949
  box
1431
1950
  ] }) });
1432
1951
  }
1433
- return /* @__PURE__ */ jsx20(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs13(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
1952
+ return /* @__PURE__ */ jsx28(BaseField2.Root, { disabled, children: /* @__PURE__ */ jsxs20(BaseField2.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
1434
1953
  box,
1435
- /* @__PURE__ */ jsx20("span", { className: WORDS_CLASSES, children: label })
1436
- ] }) });
1437
- }
1438
-
1439
- // src/Chip.tsx
1440
- import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1441
- var typeStyles = {
1442
- neutral: "bg-bg-inset text-text-primary",
1443
- brand: "bg-accent-muted text-accent-text signal:border signal:border-accent-outline",
1444
- info: "bg-info-muted text-info-default signal:border signal:border-info-outline",
1445
- warning: "bg-warning-muted text-warning-default signal:border signal:border-warning-outline signal:shadow-glow-warning",
1446
- success: "bg-success-muted text-success-default signal:border signal:border-success-outline",
1447
- error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
1448
- };
1449
- function Chip({ type = "neutral", label, leadingIcon, trailingIcon, href, onClick, className }) {
1450
- const classes = 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);
1451
- const inside = /* @__PURE__ */ jsxs14(Fragment4, { children: [
1452
- leadingIcon && /* @__PURE__ */ jsx21("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
1453
- label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
1454
- // of growing past it — Ship's project chip on an issue row
1455
- // (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
1456
- // `truncate`, because `truncate` is `overflow: hidden` on both axes and
1457
- // the label's line box (11px under Signal) is tighter than its glyphs —
1458
- // the screenshot diff caught every descender cut off. `clip` is the
1459
- // one overflow that leaves the other axis visible. A chip with no cap
1460
- // draws exactly as before.
1461
- /* @__PURE__ */ jsx21("span", { className: cn("min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap signal:tracking-wide", CHIP_TEXT_CLASSES), children: label }),
1462
- trailingIcon && /* @__PURE__ */ jsx21("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
1463
- ] });
1464
- if (href) return /* @__PURE__ */ jsx21("a", { href, onClick, className: cn("relative", classes), children: inside });
1465
- return /* @__PURE__ */ jsx21("div", { className: classes, children: inside });
1466
- }
1467
-
1468
- // src/CommandPalette.tsx
1469
- import {
1470
- createContext as createContext5,
1471
- useContext as useContext5,
1472
- useEffect as useEffect3,
1473
- useLayoutEffect as useLayoutEffect3,
1474
- useMemo as useMemo2,
1475
- useRef as useRef5,
1476
- useState as useState4
1477
- } from "react";
1478
- import { Dialog as Dialog2 } from "@base-ui/react/dialog";
1479
- import { Autocomplete } from "@base-ui/react/autocomplete";
1480
- import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
1481
-
1482
- // src/ChipInput.tsx
1483
- import { useMemo, useState as useState3 } from "react";
1484
- import { Button as BaseButton4 } from "@base-ui/react/button";
1485
- import { Combobox } from "@base-ui/react/combobox";
1486
- import { IconX as IconX4 } from "@tabler/icons-react";
1487
- import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1488
- var CHIP_BOX = (
1489
- // Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
1490
- // rounded-sm corners — never a forced circle — and the chip's corner
1491
- // follows concentrically: 4px face + 2px inset = rounded-md.
1492
- "inline-flex items-center gap-1.5 bg-bg-elevated border border-border-subtle rounded-md py-0.5 max-h-[24px]"
1493
- );
1494
- var CHIP_LABEL = "text-caption font-medium text-text-primary";
1495
- var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
1496
- var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
1497
- function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
1498
- return /* @__PURE__ */ jsxs15("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
1499
- leading && /* @__PURE__ */ jsx22("span", { className: "flex shrink-0 items-center", children: leading }),
1500
- /* @__PURE__ */ jsx22("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
1501
- onRemove && /* @__PURE__ */ jsx22(
1502
- BaseButton4,
1503
- {
1504
- type: "button",
1505
- onClick: (e) => {
1506
- e.stopPropagation();
1507
- onRemove();
1508
- },
1509
- className: cn(CHIP_REMOVE, truncate && "shrink-0"),
1510
- "aria-label": removeLabel ?? `Remove ${label}`,
1511
- children: /* @__PURE__ */ jsx22(IconX4, { size: 10, stroke: 1.5 })
1512
- }
1513
- )
1514
- ] });
1515
- }
1516
- function ChipInput({
1517
- value,
1518
- onChange,
1519
- options,
1520
- placeholder = "Search\u2026",
1521
- autoFocus,
1522
- excludeIds = [],
1523
- chipLeading,
1524
- rowLeading,
1525
- ...aria
1526
- }) {
1527
- const [query, setQuery] = useState3("");
1528
- const [box, setBox] = useState3(null);
1529
- const available = useMemo(() => {
1530
- const chosen = new Set(value.map((o) => o.id));
1531
- const excluded = new Set(excludeIds);
1532
- return options.filter((o) => !chosen.has(o.id) && !excluded.has(o.id));
1533
- }, [options, value, excludeIds]);
1534
- const filter = useMemo(
1535
- () => (item, q) => {
1536
- const needle = q.trim().toLowerCase();
1537
- if (!needle) return true;
1538
- return item.label.toLowerCase().includes(needle) || (item.description ?? "").toLowerCase().includes(needle);
1539
- },
1540
- []
1541
- );
1542
- const open = query.trim().length > 0;
1543
- const ariaLabel = aria["aria-label"] ?? (value.length > 0 ? placeholder : void 0);
1544
- const naming = {
1545
- ...ariaLabel !== void 0 && { "aria-label": ariaLabel },
1546
- ...aria["aria-labelledby"] !== void 0 && { "aria-labelledby": aria["aria-labelledby"] }
1547
- };
1548
- function removeLast() {
1549
- if (value.length > 0) onChange(value.slice(0, -1));
1550
- }
1551
- function onInputKeyDown(event) {
1552
- if (event.key === "Backspace" && query === "" && value.length > 0) {
1553
- event.preventDefault();
1554
- event.stopPropagation();
1555
- removeLast();
1556
- return;
1557
- }
1558
- if (event.key === "Escape" && query !== "") {
1559
- event.preventDefault();
1560
- event.stopPropagation();
1561
- setQuery("");
1562
- }
1563
- }
1564
- return /* @__PURE__ */ jsxs15(
1565
- Combobox.Root,
1566
- {
1567
- multiple: true,
1568
- items: available,
1569
- value,
1570
- onValueChange: (next) => {
1571
- onChange(next);
1572
- setQuery("");
1573
- },
1574
- inputValue: query,
1575
- onInputValueChange: setQuery,
1576
- open,
1577
- openOnInputClick: false,
1578
- filter,
1579
- itemToStringLabel: (option) => option.label,
1580
- children: [
1581
- /* @__PURE__ */ jsxs15(Combobox.Chips, { ref: setBox, className: cn(FIELD_SHELL_CLASSES, "focus-within:border-border-focus focus-within:hover:border-border-focus group-hover/field:focus-within:border-border-focus px-3 py-1.5 flex flex-wrap items-center gap-1.5 min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring"), children: [
1582
- value.map((option) => /* @__PURE__ */ jsxs15(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
1583
- chipLeading && /* @__PURE__ */ jsx22("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
1584
- /* @__PURE__ */ jsx22("span", { className: CHIP_LABEL, children: option.label }),
1585
- /* @__PURE__ */ jsx22(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx22(IconX4, { size: 10, stroke: 1.5 }) })
1586
- ] }, option.id)),
1587
- /* @__PURE__ */ jsx22(
1588
- Combobox.Input,
1589
- {
1590
- autoFocus,
1591
- placeholder: value.length === 0 ? placeholder : "",
1592
- "aria-required": aria["aria-required"],
1593
- ...naming,
1594
- onKeyDown: onInputKeyDown,
1595
- className: cn("flex-1 min-w-[120px] text-body-2 border-none", BARE_INPUT_CLASSES)
1596
- }
1597
- )
1598
- ] }),
1599
- /* @__PURE__ */ jsx22(Combobox.Portal, { children: /* @__PURE__ */ jsx22(
1600
- Combobox.Positioner,
1601
- {
1602
- anchor: box,
1603
- sideOffset: GAP3,
1604
- collisionPadding: VIEWPORT_PAD3,
1605
- className: "z-50 data-[anchor-hidden]:hidden",
1606
- children: /* @__PURE__ */ jsx22(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx22(MenuPanel, {}), children: /* @__PURE__ */ jsx22(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx22(Combobox.List, { className: "flex flex-col gap-0.5", children: (option) => /* @__PURE__ */ jsx22(
1607
- Combobox.Item,
1608
- {
1609
- value: option,
1610
- render: /* @__PURE__ */ jsx22(
1611
- MenuItem,
1612
- {
1613
- size: "tall",
1614
- leading: rowLeading?.(option),
1615
- label: option.label,
1616
- description: option.description
1617
- }
1618
- )
1619
- },
1620
- option.id
1621
- ) }) }) })
1622
- }
1623
- ) })
1624
- ]
1625
- }
1626
- );
1954
+ /* @__PURE__ */ jsx28("span", { className: WORDS_CLASSES, children: label })
1955
+ ] }) });
1627
1956
  }
1628
- var GAP3 = 4;
1629
- var VIEWPORT_PAD3 = 8;
1957
+
1958
+ // src/CommandPalette.tsx
1959
+ import {
1960
+ createContext as createContext5,
1961
+ useContext as useContext5,
1962
+ useEffect as useEffect3,
1963
+ useLayoutEffect as useLayoutEffect3,
1964
+ useMemo as useMemo2,
1965
+ useRef as useRef6,
1966
+ useState as useState5
1967
+ } from "react";
1968
+ import { Dialog as Dialog3 } from "@base-ui/react/dialog";
1969
+ import { Autocomplete } from "@base-ui/react/autocomplete";
1970
+ import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
1630
1971
 
1631
1972
  // src/EmptyState.tsx
1632
1973
  import { IconMessage2 } from "@tabler/icons-react";
1633
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1974
+ import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
1634
1975
  function EmptyState({ icon, message, scope = "page", action, className }) {
1635
1976
  if (scope === "section") {
1636
- return /* @__PURE__ */ jsx23("p", { className: cn("text-caption text-text-muted", className), children: message });
1977
+ return /* @__PURE__ */ jsx29("p", { className: cn("text-caption text-text-muted", className), children: message });
1637
1978
  }
1638
- return /* @__PURE__ */ jsxs16("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1639
- /* @__PURE__ */ jsx23("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx23(IconMessage2, { size: 16, stroke: 1.5 }) }),
1640
- /* @__PURE__ */ jsx23("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
1641
- action && /* @__PURE__ */ jsx23(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
1979
+ return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1980
+ /* @__PURE__ */ jsx29("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx29(IconMessage2, { size: 16, stroke: 1.5 }) }),
1981
+ /* @__PURE__ */ jsx29("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
1982
+ action && /* @__PURE__ */ jsx29(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
1642
1983
  ] });
1643
1984
  }
1644
1985
 
1645
- // src/Field.tsx
1646
- import { cloneElement, isValidElement } from "react";
1647
- import { Field as BaseField2 } from "@base-ui/react/field";
1648
- import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1649
- var LINE_STYLES = {
1650
- helper: "text-caption text-text-muted",
1651
- warning: "text-caption text-warning-default",
1652
- error: "text-caption text-error-default"
1653
- };
1654
- function Field({ label, required = false, helper, error, children }) {
1655
- const control = required && isValidElement(children) ? cloneElement(children, {
1656
- "aria-required": children.props["aria-required"] ?? true
1657
- }) : children;
1658
- return (
1659
- // `group/field`: the label, the box and the line under it are one thing under the pointer —
1660
- // anywhere in it strengthens the box's border, as hovering the box does (Katerina, 28 September).
1661
- // Before, the 8px between the label and the box was a gap where the border went out again.
1662
- /* @__PURE__ */ jsxs17(BaseField2.Root, { invalid: !!error, className: "group/field flex flex-col gap-2", children: [
1663
- /* @__PURE__ */ jsxs17(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1664
- label,
1665
- required && /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1666
- ] }),
1667
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1.5", children: [
1668
- control,
1669
- error != null ? /* @__PURE__ */ jsx24(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx24(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
1670
- ] })
1671
- ] })
1672
- );
1673
- }
1674
- function FieldLine({ tone = "helper", children, className }) {
1675
- return /* @__PURE__ */ jsx24("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1676
- }
1677
-
1678
- // src/Form.tsx
1679
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef4 } from "react";
1680
- import { Fieldset } from "@base-ui/react/fieldset";
1681
- import { Form as BaseForm } from "@base-ui/react/form";
1682
- import { jsx as jsx25 } from "react/jsx-runtime";
1683
- var FIELDS_CLASSES = "flex flex-col gap-6";
1684
- var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
1685
- var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1686
- function usable(element) {
1687
- return element instanceof HTMLElement && element.isConnected && element.matches(CONTROL) && !element.matches(":disabled") && element.getAttribute("aria-disabled") !== "true";
1688
- }
1689
- function firstInvalid(form) {
1690
- for (const marked of form.querySelectorAll("[data-invalid]")) {
1691
- if (usable(marked)) return marked;
1692
- const inside = Array.from(marked.querySelectorAll(CONTROL)).find(usable);
1693
- if (inside) return inside;
1694
- }
1695
- return void 0;
1696
- }
1697
- function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fields", className, children, ...props }) {
1698
- const outerBusy = useFormBusy();
1699
- const busy = ownBusy || outerBusy;
1700
- const form = useRef4(null);
1701
- const busyNow = useRef4(busy);
1702
- busyNow.current = busy;
1703
- const sender = useRef4(null);
1704
- const holding = useRef4(false);
1705
- const lastInside = useRef4(null);
1706
- useLayoutEffect2(() => {
1707
- const element = form.current;
1708
- if (!element) return;
1709
- if (busy) {
1710
- const active = document.activeElement;
1711
- const from = active && active !== element && element.contains(active) ? active : !active || active === document.body ? lastInside.current : null;
1712
- if (from?.isConnected) {
1713
- sender.current = from;
1714
- holding.current = true;
1715
- element.focus();
1716
- }
1717
- return;
1718
- }
1719
- if (!holding.current) return;
1720
- holding.current = false;
1721
- if (document.activeElement !== element && document.activeElement !== document.body) return;
1722
- const target = firstInvalid(element) ?? (usable(sender.current) ? sender.current : Array.from(element.querySelectorAll(CONTROL)).find(usable));
1723
- sender.current = null;
1724
- target?.focus();
1725
- }, [busy]);
1726
- const onKeyDown = (event) => {
1727
- props.onKeyDown?.(event);
1728
- if (event.key !== "Enter" || event.defaultPrevented || event.nativeEvent.isComposing) return;
1729
- const target = event.target;
1730
- const inInput = target instanceof HTMLInputElement;
1731
- if (inInput) event.preventDefault();
1732
- if (event.altKey || event.shiftKey) return;
1733
- if (event.ctrlKey || event.metaKey) {
1734
- event.preventDefault();
1735
- form.current?.requestSubmit();
1736
- return;
1737
- }
1738
- if (!inInput) return;
1739
- const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
1740
- if (enterSends && oneLine) form.current?.requestSubmit();
1741
- };
1742
- return /* @__PURE__ */ jsx25(
1743
- BaseForm,
1744
- {
1745
- ref: form,
1746
- ...props,
1747
- tabIndex: busy ? -1 : props.tabIndex,
1748
- className: cn("outline-none", layout === "fields" && FIELDS_CLASSES, className),
1749
- onFocus: (event) => {
1750
- if (event.target !== form.current) lastInside.current = event.target;
1751
- props.onFocus?.(event);
1752
- },
1753
- onBlur: (event) => {
1754
- const next = event.relatedTarget;
1755
- if (next && !form.current?.contains(next)) lastInside.current = null;
1756
- props.onBlur?.(event);
1757
- },
1758
- onKeyDown,
1759
- onSubmit: (event) => {
1760
- if (event.target !== event.currentTarget) return;
1761
- event.preventDefault();
1762
- if (busyNow.current) return;
1763
- void onSubmit();
1764
- },
1765
- children: /* @__PURE__ */ jsx25(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx25(FormBusyContext.Provider, { value: busy, children }) })
1766
- }
1767
- );
1768
- }
1769
-
1770
1986
  // src/Skeleton.tsx
1771
- import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
1987
+ import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
1772
1988
  function SkeletonBar({ className, style }) {
1773
- return /* @__PURE__ */ jsx26("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1989
+ return /* @__PURE__ */ jsx30("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1774
1990
  }
1775
1991
  var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
1776
1992
  function SkeletonRow({ barWidth = 130 }) {
1777
- return /* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1778
- /* @__PURE__ */ jsx26(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1779
- /* @__PURE__ */ jsx26(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1993
+ return /* @__PURE__ */ jsxs22("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1994
+ /* @__PURE__ */ jsx30(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1995
+ /* @__PURE__ */ jsx30(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1780
1996
  ] });
1781
1997
  }
1782
1998
  function SkeletonList({ rows = 8, className }) {
1783
- return /* @__PURE__ */ jsx26("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx26(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1999
+ return /* @__PURE__ */ jsx30("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx30(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1784
2000
  }
1785
2001
 
1786
2002
  // src/CommandPalette.tsx
1787
- import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
2003
+ import { Fragment as Fragment6, jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
1788
2004
  var PaletteContext = createContext5(null);
1789
2005
  function usePalette(part) {
1790
2006
  const palette = useContext5(PaletteContext);
@@ -1799,7 +2015,7 @@ function firstControl(popup) {
1799
2015
  return popup.querySelector("[data-command-palette-fields]")?.querySelector(CONTROL2) ?? null;
1800
2016
  }
1801
2017
  function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", children }) {
1802
- const popupRef = useRef5(null);
2018
+ const popupRef = useRef6(null);
1803
2019
  useEffect3(() => {
1804
2020
  if (!open) return;
1805
2021
  const frame = requestAnimationFrame(() => {
@@ -1810,10 +2026,10 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
1810
2026
  return () => cancelAnimationFrame(frame);
1811
2027
  });
1812
2028
  const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
1813
- return /* @__PURE__ */ jsx27(Dialog2.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs19(Dialog2.Portal, { children: [
1814
- /* @__PURE__ */ jsx27(Dialog2.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1815
- /* @__PURE__ */ jsx27(Dialog2.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx27(
1816
- Dialog2.Popup,
2029
+ return /* @__PURE__ */ jsx31(Dialog3.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs23(Dialog3.Portal, { children: [
2030
+ /* @__PURE__ */ jsx31(Dialog3.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
2031
+ /* @__PURE__ */ jsx31(Dialog3.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx31(
2032
+ Dialog3.Popup,
1817
2033
  {
1818
2034
  ref: popupRef,
1819
2035
  "aria-label": label,
@@ -1822,13 +2038,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
1822
2038
  if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
1823
2039
  },
1824
2040
  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",
1825
- children: /* @__PURE__ */ jsx27(PaletteContext.Provider, { value: context, children })
2041
+ children: /* @__PURE__ */ jsx31(PaletteContext.Provider, { value: context, children })
1826
2042
  }
1827
2043
  ) })
1828
2044
  ] }) });
1829
2045
  }
1830
2046
  function LevelChip({ chip, onBack }) {
1831
- return /* @__PURE__ */ jsx27(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
2047
+ return /* @__PURE__ */ jsx31(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
1832
2048
  }
1833
2049
  function useBack(chip, popupRef) {
1834
2050
  return () => {
@@ -1839,10 +2055,10 @@ function useBack(chip, popupRef) {
1839
2055
  }
1840
2056
  function Footer({ keys }) {
1841
2057
  const { where } = usePalette("The footer");
1842
- return /* @__PURE__ */ jsxs19("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 leaf:font-mono leaf:text-small", children: [
1843
- /* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 truncate", children: where }),
1844
- keys.map(([key, word]) => /* @__PURE__ */ jsxs19("span", { className: "flex shrink-0 items-center gap-1.5", children: [
1845
- /* @__PURE__ */ jsx27(Kbd, { children: key }),
2058
+ return /* @__PURE__ */ jsxs23("div", { className: cn("flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5", MONO_CAPTION_CLASSES, "signal:text-text-muted leaf:font-mono leaf:text-small"), children: [
2059
+ /* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate", children: where }),
2060
+ keys.map(([key, word]) => /* @__PURE__ */ jsxs23("span", { className: "flex shrink-0 items-center gap-1.5", children: [
2061
+ /* @__PURE__ */ jsx31(Kbd, { children: key }),
1846
2062
  " ",
1847
2063
  word
1848
2064
  ] }, key))
@@ -1854,12 +2070,12 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1854
2070
  const back = useBack(chip, popupRef);
1855
2071
  const items = useMemo2(() => groups.filter((g) => g.rows.length > 0).map((g) => ({ value: g.label, items: g.rows })), [groups]);
1856
2072
  const rows = items.flatMap((g) => g.items);
1857
- const [litId, setLitId] = useState4();
2073
+ const [litId, setLitId] = useState5();
1858
2074
  const lit = litId === void 0 ? void 0 : rows.find((r) => r.id === litId);
1859
- const inputRef = useRef5(null);
1860
- const reported = useRef5({});
1861
- const settled = useRef5(null);
1862
- const moved = useRef5(false);
2075
+ const inputRef = useRef6(null);
2076
+ const reported = useRef6({});
2077
+ const settled = useRef6(null);
2078
+ const moved = useRef6(false);
1863
2079
  useLayoutEffect3(() => {
1864
2080
  const before = settled.current;
1865
2081
  const now = reported.current;
@@ -1919,7 +2135,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1919
2135
  ...chip && query === "" ? [["Backspace", "back"]] : [],
1920
2136
  ["Esc", "close"]
1921
2137
  ];
1922
- return /* @__PURE__ */ jsxs19(
2138
+ return /* @__PURE__ */ jsxs23(
1923
2139
  Autocomplete.Root,
1924
2140
  {
1925
2141
  items,
@@ -1942,10 +2158,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1942
2158
  setLitId(id);
1943
2159
  },
1944
2160
  children: [
1945
- /* @__PURE__ */ jsxs19("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1946
- /* @__PURE__ */ jsx27(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
1947
- chip && /* @__PURE__ */ jsx27(LevelChip, { chip, onBack: back }),
1948
- /* @__PURE__ */ jsx27(
2161
+ /* @__PURE__ */ jsxs23("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
2162
+ /* @__PURE__ */ jsx31(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
2163
+ chip && /* @__PURE__ */ jsx31(LevelChip, { chip, onBack: back }),
2164
+ /* @__PURE__ */ jsx31(
1949
2165
  Autocomplete.Input,
1950
2166
  {
1951
2167
  ref: inputRef,
@@ -1957,43 +2173,43 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1957
2173
  }
1958
2174
  )
1959
2175
  ] }),
1960
- /* @__PURE__ */ jsxs19(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
1961
- children != null && /* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
1962
- /* @__PURE__ */ jsx27(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs19(Autocomplete.Group, { items: group.items, className: "flex flex-col gap-0.5", children: [
1963
- /* @__PURE__ */ jsx27(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx27(SectionLabel, { tone: "secondary", children: group.value }) }),
1964
- /* @__PURE__ */ jsx27(Autocomplete.Collection, { children: (row) => (
2176
+ /* @__PURE__ */ jsxs23(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
2177
+ children != null && /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
2178
+ /* @__PURE__ */ jsx31(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs23(Autocomplete.Group, { items: group.items, className: "flex flex-col gap-0.5", children: [
2179
+ /* @__PURE__ */ jsx31(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx31(SectionLabel, { tone: "secondary", children: group.value }) }),
2180
+ /* @__PURE__ */ jsx31(Autocomplete.Collection, { children: (row) => (
1965
2181
  /* The menu row, as the list's own option — the way Select
1966
2182
  puts it on `Select.Item`. One row, two parts. */
1967
- /* @__PURE__ */ jsx27(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx27(
2183
+ /* @__PURE__ */ jsx31(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx31(
1968
2184
  MenuItemBody,
1969
2185
  {
1970
2186
  size: "tall",
1971
2187
  label: row.label,
1972
2188
  description: row.description,
1973
- leading: /* @__PURE__ */ jsx27(RowLeading, { row }),
2189
+ leading: /* @__PURE__ */ jsx31(RowLeading, { row }),
1974
2190
  submenu: !!row.onGoIn,
1975
- hint: row.onGoIn ? /* @__PURE__ */ jsx27(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx27(EnterHint, {})
2191
+ hint: row.onGoIn ? /* @__PURE__ */ jsx31(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx31(EnterHint, {})
1976
2192
  }
1977
2193
  ) }, row.id)
1978
2194
  ) })
1979
2195
  ] }, group.value) }),
1980
- /* @__PURE__ */ jsx27(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs19(Fragment5, { children: [
1981
- /* @__PURE__ */ jsx27(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
1982
- /* @__PURE__ */ jsx27("span", { className: "text-caption text-text-muted", children: pending })
2196
+ /* @__PURE__ */ jsx31(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs23(Fragment6, { children: [
2197
+ /* @__PURE__ */ jsx31(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
2198
+ /* @__PURE__ */ jsx31("span", { className: "text-caption text-text-muted", children: pending })
1983
2199
  ] }) }),
1984
- notes.map((note) => /* @__PURE__ */ jsx27("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx27(FieldLine, { children: note }) }, note)),
1985
- /* @__PURE__ */ jsx27(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx27(EmptyState, { scope: "section", message: empty }) })
2200
+ notes.map((note) => /* @__PURE__ */ jsx31("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx31(FieldLine, { children: note }) }, note)),
2201
+ /* @__PURE__ */ jsx31(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx31(EmptyState, { scope: "section", message: empty }) })
1986
2202
  ] }),
1987
- /* @__PURE__ */ jsx27(Footer, { keys })
2203
+ /* @__PURE__ */ jsx31(Footer, { keys })
1988
2204
  ]
1989
2205
  }
1990
2206
  );
1991
2207
  }
1992
2208
  function RowLeading({ row }) {
1993
2209
  if (row.icon != null) {
1994
- return /* @__PURE__ */ jsx27("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
2210
+ return /* @__PURE__ */ jsx31("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
1995
2211
  }
1996
- return /* @__PURE__ */ jsx27("span", { className: "flex size-8 items-center justify-center", children: row.leading });
2212
+ return /* @__PURE__ */ jsx31("span", { className: "flex size-8 items-center justify-center", children: row.leading });
1997
2213
  }
1998
2214
  var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1999
2215
  function isTextField(el) {
@@ -2003,9 +2219,9 @@ function isTextField(el) {
2003
2219
  function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, working, error, children }) {
2004
2220
  const { modKey, popupRef } = usePalette("CommandPaletteForm");
2005
2221
  const back = useBack(chip, popupRef);
2006
- const frameRef = useRef5(null);
2222
+ const frameRef = useRef6(null);
2007
2223
  const busy = !!working;
2008
- const busyRef = useRef5(busy);
2224
+ const busyRef = useRef6(busy);
2009
2225
  busyRef.current = busy;
2010
2226
  const firstInvalid2 = () => frameRef.current?.querySelector("[data-invalid]")?.querySelector(CONTROL2) ?? null;
2011
2227
  const submit = () => {
@@ -2021,7 +2237,7 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
2021
2237
  if (isTextField(el)) return el.value === "";
2022
2238
  return ![...frame.querySelectorAll("input, textarea")].some(isTextField);
2023
2239
  };
2024
- const [backNamed, setBackNamed] = useState4(false);
2240
+ const [backNamed, setBackNamed] = useState5(false);
2025
2241
  const measure = () => setBackNamed(backWorksFrom(document.activeElement));
2026
2242
  useLayoutEffect3(measure);
2027
2243
  const onKeyDown = (e) => {
@@ -2035,65 +2251,65 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
2035
2251
  ...backNamed ? [["Backspace", "back"]] : [],
2036
2252
  ["Esc", "close"]
2037
2253
  ];
2038
- return /* @__PURE__ */ jsxs19("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
2039
- /* @__PURE__ */ jsxs19("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
2040
- icon != null && /* @__PURE__ */ jsx27("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
2041
- /* @__PURE__ */ jsx27(LevelChip, { chip, onBack: back })
2254
+ return /* @__PURE__ */ jsxs23("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
2255
+ /* @__PURE__ */ jsxs23("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
2256
+ icon != null && /* @__PURE__ */ jsx31("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
2257
+ /* @__PURE__ */ jsx31(LevelChip, { chip, onBack: back })
2042
2258
  ] }),
2043
- /* @__PURE__ */ jsxs19(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, layout: "free", className: "flex min-h-0 flex-col", children: [
2044
- /* @__PURE__ */ jsx27(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx27("div", { className: FIELDS_CLASSES, children }) }),
2045
- /* @__PURE__ */ jsxs19("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
2046
- /* @__PURE__ */ jsx27("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx27(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx27(FieldLine, { tone: "error", children: error }) : null }),
2047
- /* @__PURE__ */ jsx27(
2259
+ /* @__PURE__ */ jsxs23(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, layout: "free", className: "flex min-h-0 flex-col", children: [
2260
+ /* @__PURE__ */ jsx31(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx31("div", { className: FIELDS_CLASSES, children }) }),
2261
+ /* @__PURE__ */ jsxs23("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
2262
+ /* @__PURE__ */ jsx31("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx31(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx31(FieldLine, { tone: "error", children: error }) : null }),
2263
+ /* @__PURE__ */ jsx31(
2048
2264
  Button,
2049
2265
  {
2050
2266
  type: "submit",
2051
2267
  variant: "primary",
2052
2268
  disabled: busy,
2053
2269
  disabledReason: busy ? void 0 : submitWaits,
2054
- leadingIcon: busy ? /* @__PURE__ */ jsx27(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
2270
+ leadingIcon: busy ? /* @__PURE__ */ jsx31(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
2055
2271
  children: working ? working.button : submitLabel
2056
2272
  }
2057
2273
  )
2058
2274
  ] })
2059
2275
  ] }),
2060
- /* @__PURE__ */ jsx27(Footer, { keys })
2276
+ /* @__PURE__ */ jsx31(Footer, { keys })
2061
2277
  ] });
2062
2278
  }
2063
2279
  var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
2064
2280
  function CommandPaletteWorking({ children, bars = 2 }) {
2065
- return /* @__PURE__ */ jsxs19("div", { role: "status", className: "flex flex-col gap-2", children: [
2066
- /* @__PURE__ */ jsxs19("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
2067
- /* @__PURE__ */ jsx27(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
2281
+ return /* @__PURE__ */ jsxs23("div", { role: "status", className: "flex flex-col gap-2", children: [
2282
+ /* @__PURE__ */ jsxs23("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
2283
+ /* @__PURE__ */ jsx31(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
2068
2284
  children
2069
2285
  ] }),
2070
- BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx27(SkeletonBar, { className: cn("h-3", width) }, width))
2286
+ BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx31(SkeletonBar, { className: cn("h-3", width) }, width))
2071
2287
  ] });
2072
2288
  }
2073
2289
  function CommandPaletteAnswer({ children, note }) {
2074
2290
  const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
2075
- return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2", children: [
2076
- paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx27("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
2077
- (part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx27("sup", { className: "ml-0.5 font-mono text-small text-accent-text", children: part.slice(1, -1) }, j) : part
2291
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-2", children: [
2292
+ paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx31("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
2293
+ (part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx31("sup", { className: "ml-0.5 font-mono text-small text-accent-text", children: part.slice(1, -1) }, j) : part
2078
2294
  ) }, i)),
2079
- note && /* @__PURE__ */ jsx27(FieldLine, { children: note })
2295
+ note && /* @__PURE__ */ jsx31(FieldLine, { children: note })
2080
2296
  ] });
2081
2297
  }
2082
2298
  function CommandPaletteQuote({ children }) {
2083
- return /* @__PURE__ */ jsx27("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
2299
+ return /* @__PURE__ */ jsx31("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
2084
2300
  }
2085
2301
  function CommandPaletteProposal({ source, mark, children }) {
2086
- return /* @__PURE__ */ jsxs19(Card, { fill: "surface", className: "flex flex-col gap-1 p-3", children: [
2087
- /* @__PURE__ */ jsxs19("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
2302
+ return /* @__PURE__ */ jsxs23(Card, { fill: "surface", className: "flex flex-col gap-1 p-3", children: [
2303
+ /* @__PURE__ */ jsxs23("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
2088
2304
  mark,
2089
2305
  source
2090
2306
  ] }),
2091
- /* @__PURE__ */ jsx27("span", { className: "text-body-2 text-text-primary", children })
2307
+ /* @__PURE__ */ jsx31("span", { className: "text-body-2 text-text-primary", children })
2092
2308
  ] });
2093
2309
  }
2094
2310
 
2095
2311
  // src/InlineChip.tsx
2096
- import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
2312
+ import { Fragment as Fragment7, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
2097
2313
  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";
2098
2314
  var INLINE_CHIP_TONE_CLASSES = {
2099
2315
  /** A thing or a place — anything that is not a person. */
@@ -2115,19 +2331,19 @@ function inlineChipClassName(tone, className) {
2115
2331
  return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
2116
2332
  }
2117
2333
  function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
2118
- const body = /* @__PURE__ */ jsxs20(Fragment6, { children: [
2119
- icon && /* @__PURE__ */ jsx28("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
2334
+ const body = /* @__PURE__ */ jsxs24(Fragment7, { children: [
2335
+ icon && /* @__PURE__ */ jsx32("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
2120
2336
  children
2121
2337
  ] });
2122
2338
  const classes = inlineChipClassName(tone, className);
2123
2339
  if (href === void 0) {
2124
- return /* @__PURE__ */ jsx28("span", { className: classes, ...props, children: body });
2340
+ return /* @__PURE__ */ jsx32("span", { className: classes, ...props, children: body });
2125
2341
  }
2126
- return /* @__PURE__ */ jsx28("a", { href, className: classes, ...props, children: body });
2342
+ return /* @__PURE__ */ jsx32("a", { href, className: classes, ...props, children: body });
2127
2343
  }
2128
2344
 
2129
2345
  // src/RichText.tsx
2130
- import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
2346
+ import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs25 } from "react/jsx-runtime";
2131
2347
  var RICH_TEXT_CLASSES = {
2132
2348
  base: "flex flex-col gap-1 break-words text-text-secondary",
2133
2349
  /* A heading binds to what follows it: 12px above (8 and the 4px gap), 8px below (4 and the gap); two headings in a row, 12px apart. Level 3 keeps the text's colour, one step lower. */
@@ -2159,35 +2375,35 @@ function textWithLinks(text, renderText) {
2159
2375
  return parts.map((part, i) => {
2160
2376
  const written = part.match(WRITTEN_LINK);
2161
2377
  if (written) {
2162
- return /* @__PURE__ */ jsx29("span", { className: "break-words", children: /* @__PURE__ */ jsx29(Link, { href: written[2], external: true, onClick: keepToLink, children: written[1] }) }, i);
2378
+ return /* @__PURE__ */ jsx33("span", { className: "break-words", children: /* @__PURE__ */ jsx33(Link, { href: written[2], external: true, onClick: keepToLink, children: written[1] }) }, i);
2163
2379
  }
2164
2380
  const bare = i % 2 === 1 ? part.match(BARE_LINK) : null;
2165
2381
  if (bare) {
2166
2382
  return (
2167
2383
  // An address has no spaces to wrap at, so it may break anywhere.
2168
- /* @__PURE__ */ jsxs21("span", { className: "break-all", children: [
2169
- /* @__PURE__ */ jsx29(Link, { href: bare[1], external: true, onClick: keepToLink, children: bare[1] }),
2384
+ /* @__PURE__ */ jsxs25("span", { className: "break-all", children: [
2385
+ /* @__PURE__ */ jsx33(Link, { href: bare[1], external: true, onClick: keepToLink, children: bare[1] }),
2170
2386
  bare[2]
2171
2387
  ] }, i)
2172
2388
  );
2173
2389
  }
2174
- return part ? /* @__PURE__ */ jsx29("span", { children: renderText(part) }, i) : null;
2390
+ return part ? /* @__PURE__ */ jsx33("span", { children: renderText(part) }, i) : null;
2175
2391
  });
2176
2392
  }
2177
2393
  function Runs({ runs, draw }) {
2178
- return /* @__PURE__ */ jsx29(Fragment7, { children: (runs ?? []).map((run, i) => {
2179
- if (run.reference) return /* @__PURE__ */ jsx29("span", { children: draw.renderReference(run.reference, run) }, i);
2394
+ return /* @__PURE__ */ jsx33(Fragment8, { children: (runs ?? []).map((run, i) => {
2395
+ if (run.reference) return /* @__PURE__ */ jsx33("span", { children: draw.renderReference(run.reference, run) }, i);
2180
2396
  if (run.marks.includes("code")) {
2181
- return /* @__PURE__ */ jsx29("code", { children: run.text }, i);
2397
+ return /* @__PURE__ */ jsx33("code", { children: run.text }, i);
2182
2398
  }
2183
- let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs21("span", { children: [
2184
- j > 0 && /* @__PURE__ */ jsx29("br", {}),
2399
+ let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs25("span", { children: [
2400
+ j > 0 && /* @__PURE__ */ jsx33("br", {}),
2185
2401
  textWithLinks(line, draw.renderText)
2186
2402
  ] }, j));
2187
- if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx29("u", { children: node });
2188
- if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx29("em", { children: node });
2189
- if (run.marks.includes("bold")) node = /* @__PURE__ */ jsx29("strong", { children: node });
2190
- return /* @__PURE__ */ jsx29("span", { children: node }, i);
2403
+ if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx33("u", { children: node });
2404
+ if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx33("em", { children: node });
2405
+ if (run.marks.includes("bold")) node = /* @__PURE__ */ jsx33("strong", { children: node });
2406
+ return /* @__PURE__ */ jsx33("span", { children: node }, i);
2191
2407
  }) });
2192
2408
  }
2193
2409
  var named = (block) => block.typeName ?? block.type;
@@ -2198,15 +2414,15 @@ function Table({ block, draw }) {
2198
2414
  const header = named(cell) === "tableHeader";
2199
2415
  const Cell = header ? "th" : "td";
2200
2416
  const { colspan, rowspan } = cell.attrs ?? {};
2201
- return /* @__PURE__ */ jsxs21(
2417
+ return /* @__PURE__ */ jsxs25(
2202
2418
  Cell,
2203
2419
  {
2204
2420
  "data-block-id": cell.id,
2205
2421
  colSpan: colspan && colspan > 1 ? colspan : void 0,
2206
2422
  rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
2207
2423
  children: [
2208
- (cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx29(Runs, { runs: child.inline, draw }, j)),
2209
- /* @__PURE__ */ jsx29(Runs, { runs: cell.inline, draw })
2424
+ (cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx33(Runs, { runs: child.inline, draw }, j)),
2425
+ /* @__PURE__ */ jsx33(Runs, { runs: cell.inline, draw })
2210
2426
  ]
2211
2427
  },
2212
2428
  cell.id ?? i
@@ -2214,43 +2430,43 @@ function Table({ block, draw }) {
2214
2430
  });
2215
2431
  const first = rows[0].children ?? [];
2216
2432
  const headerRow = first.length > 0 && first.every((cell) => named(cell) === "tableHeader");
2217
- return /* @__PURE__ */ jsxs21("table", { "data-block-id": block.id, children: [
2218
- headerRow && /* @__PURE__ */ jsx29("thead", { children: /* @__PURE__ */ jsx29("tr", { "data-block-id": rows[0].id, children: cells(rows[0]) }) }),
2219
- /* @__PURE__ */ jsx29("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx29("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
2433
+ return /* @__PURE__ */ jsxs25("table", { "data-block-id": block.id, children: [
2434
+ headerRow && /* @__PURE__ */ jsx33("thead", { children: /* @__PURE__ */ jsx33("tr", { "data-block-id": rows[0].id, children: cells(rows[0]) }) }),
2435
+ /* @__PURE__ */ jsx33("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx33("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
2220
2436
  ] });
2221
2437
  }
2222
2438
  function Block({ block, draw }) {
2223
2439
  const own = draw.renderBlock?.(block);
2224
2440
  if (own !== void 0) return own;
2225
- const runs = /* @__PURE__ */ jsx29(Runs, { runs: block.inline, draw });
2441
+ const runs = /* @__PURE__ */ jsx33(Runs, { runs: block.inline, draw });
2226
2442
  switch (block.type) {
2227
2443
  case "heading": {
2228
- if (block.level === 1) return /* @__PURE__ */ jsx29("h1", { "data-block-id": block.id, children: runs });
2229
- if (block.level === 3) return /* @__PURE__ */ jsx29("h3", { "data-block-id": block.id, children: runs });
2230
- return /* @__PURE__ */ jsx29("h2", { "data-block-id": block.id, children: runs });
2444
+ if (block.level === 1) return /* @__PURE__ */ jsx33("h1", { "data-block-id": block.id, children: runs });
2445
+ if (block.level === 3) return /* @__PURE__ */ jsx33("h3", { "data-block-id": block.id, children: runs });
2446
+ return /* @__PURE__ */ jsx33("h2", { "data-block-id": block.id, children: runs });
2231
2447
  }
2232
2448
  case "paragraph":
2233
- return /* @__PURE__ */ jsx29("p", { "data-block-id": block.id, children: runs });
2449
+ return /* @__PURE__ */ jsx33("p", { "data-block-id": block.id, children: runs });
2234
2450
  case "bulletList":
2235
2451
  case "orderedList": {
2236
- const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx29("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx29(Runs, { runs: item.inline, draw }) }, item.id ?? i));
2237
- return block.type === "bulletList" ? /* @__PURE__ */ jsx29("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx29("ol", { "data-block-id": block.id, start: block.start, children: items });
2452
+ const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx33("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx33(Runs, { runs: item.inline, draw }) }, item.id ?? i));
2453
+ return block.type === "bulletList" ? /* @__PURE__ */ jsx33("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx33("ol", { "data-block-id": block.id, start: block.start, children: items });
2238
2454
  }
2239
2455
  case "blockquote":
2240
- return /* @__PURE__ */ jsx29("blockquote", { "data-block-id": block.id, children: runs });
2456
+ return /* @__PURE__ */ jsx33("blockquote", { "data-block-id": block.id, children: runs });
2241
2457
  case "codeBlock":
2242
- return /* @__PURE__ */ jsx29("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx29("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
2458
+ return /* @__PURE__ */ jsx33("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx33("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
2243
2459
  case "horizontalRule":
2244
- return /* @__PURE__ */ jsx29("hr", { "data-block-id": block.id });
2460
+ return /* @__PURE__ */ jsx33("hr", { "data-block-id": block.id });
2245
2461
  case "table": {
2246
- const table = /* @__PURE__ */ jsx29(Table, { block, draw });
2462
+ const table = /* @__PURE__ */ jsx33(Table, { block, draw });
2247
2463
  if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
2248
2464
  break;
2249
2465
  }
2250
2466
  }
2251
- return /* @__PURE__ */ jsxs21("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
2467
+ return /* @__PURE__ */ jsxs25("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
2252
2468
  runs,
2253
- (block.children ?? []).map((child, i) => /* @__PURE__ */ jsx29(Block, { block: child, draw }, child.id ?? i))
2469
+ (block.children ?? []).map((child, i) => /* @__PURE__ */ jsx33(Block, { block: child, draw }, child.id ?? i))
2254
2470
  ] });
2255
2471
  }
2256
2472
  function RichText({
@@ -2262,34 +2478,34 @@ function RichText({
2262
2478
  }) {
2263
2479
  if (blocks.length === 0) return null;
2264
2480
  const draw = { renderText, renderReference, renderBlock };
2265
- return /* @__PURE__ */ jsx29("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx29(Block, { block, draw }, block.id ?? i)) });
2481
+ return /* @__PURE__ */ jsx33("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx33(Block, { block, draw }, block.id ?? i)) });
2266
2482
  }
2267
2483
 
2268
2484
  // src/IdentityMenu.tsx
2269
- import { useCallback as useCallback2, useRef as useRef6 } from "react";
2485
+ import { useCallback as useCallback2, useRef as useRef7 } from "react";
2270
2486
 
2271
2487
  // src/Person.tsx
2272
- import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
2488
+ import { jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
2273
2489
  function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
2274
2490
  return (
2275
2491
  // gap-2: the face-to-name distance is one rule (8px) wherever a person
2276
2492
  // appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
2277
2493
  // row agree by construction.
2278
- /* @__PURE__ */ jsxs22("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
2279
- /* @__PURE__ */ jsx30(Avatar, { name, src: picture, size }),
2280
- /* @__PURE__ */ jsx30("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
2494
+ /* @__PURE__ */ jsxs26("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
2495
+ /* @__PURE__ */ jsx34(Avatar, { name, src: picture, size }),
2496
+ /* @__PURE__ */ jsx34("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
2281
2497
  ] })
2282
2498
  );
2283
2499
  }
2284
2500
 
2285
2501
  // src/PersonTrigger.tsx
2286
- import { Button as BaseButton5 } from "@base-ui/react/button";
2287
- import { IconChevronDown } from "@tabler/icons-react";
2288
- import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
2502
+ import { Button as BaseButton6 } from "@base-ui/react/button";
2503
+ import { IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
2504
+ import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
2289
2505
  function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
2290
2506
  if (compact) {
2291
- return /* @__PURE__ */ jsx31(
2292
- BaseButton5,
2507
+ return /* @__PURE__ */ jsx35(
2508
+ BaseButton6,
2293
2509
  {
2294
2510
  type: "button",
2295
2511
  "aria-haspopup": "menu",
@@ -2297,14 +2513,14 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2297
2513
  "aria-label": props["aria-label"] ?? name ?? fallback,
2298
2514
  className: cn("cursor-pointer rounded-full", className),
2299
2515
  ...props,
2300
- children: /* @__PURE__ */ jsx31(Avatar, { name, src: picture, size: size ?? 36 })
2516
+ children: /* @__PURE__ */ jsx35(Avatar, { name, src: picture, size: size ?? 36 })
2301
2517
  }
2302
2518
  );
2303
2519
  }
2304
2520
  return (
2305
2521
  // @estiva-escape(no-copied-look): N5 (Katerina, 24 September: record only): a row that fills on hover, as NavItem also does
2306
- /* @__PURE__ */ jsxs23(
2307
- BaseButton5,
2522
+ /* @__PURE__ */ jsxs27(
2523
+ BaseButton6,
2308
2524
  {
2309
2525
  type: "button",
2310
2526
  "aria-haspopup": "menu",
@@ -2321,8 +2537,8 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2321
2537
  ),
2322
2538
  ...props,
2323
2539
  children: [
2324
- /* @__PURE__ */ jsx31(Person, { name, picture, fallback, size: size ?? 22 }),
2325
- /* @__PURE__ */ jsx31(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
2540
+ /* @__PURE__ */ jsx35(Person, { name, picture, fallback, size: size ?? 22 }),
2541
+ /* @__PURE__ */ jsx35(IconChevronDown2, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
2326
2542
  ]
2327
2543
  }
2328
2544
  )
@@ -2330,10 +2546,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2330
2546
  }
2331
2547
 
2332
2548
  // src/IdentityMenu.tsx
2333
- import { Fragment as Fragment8, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
2549
+ import { Fragment as Fragment9, jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
2334
2550
  function IdentityPanel({ className, onClose = () => {
2335
2551
  }, ...rest }) {
2336
- return /* @__PURE__ */ jsx32(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx32(IdentityRows, { ...rest, onClose }) });
2552
+ return /* @__PURE__ */ jsx36(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx36(IdentityRows, { ...rest, onClose }) });
2337
2553
  }
2338
2554
  function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
2339
2555
  const act = (action) => () => {
@@ -2341,53 +2557,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
2341
2557
  action();
2342
2558
  };
2343
2559
  const appRows = typeof children === "function" ? children(onClose) : children;
2344
- return /* @__PURE__ */ jsxs24(Fragment8, { children: [
2345
- /* @__PURE__ */ jsxs24(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
2346
- /* @__PURE__ */ jsx32(MenuRow, { children: /* @__PURE__ */ jsx32("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx32(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
2347
- /* @__PURE__ */ jsx32(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." }),
2348
- me.email && /* @__PURE__ */ jsxs24(Note, { children: [
2560
+ return /* @__PURE__ */ jsxs28(Fragment9, { children: [
2561
+ /* @__PURE__ */ jsxs28(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
2562
+ /* @__PURE__ */ jsx36(MenuRow, { children: /* @__PURE__ */ jsx36("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx36(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
2563
+ /* @__PURE__ */ jsx36(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." }),
2564
+ me.email && /* @__PURE__ */ jsxs28(Note, { children: [
2349
2565
  me.email,
2350
2566
  " \xB7 known to Estiva, never published to the relay"
2351
2567
  ] })
2352
2568
  ] }),
2353
- relayUrl && /* @__PURE__ */ jsxs24(Fragment8, { children: [
2354
- /* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }),
2355
- /* @__PURE__ */ jsxs24(MenuSection, { label: "Workspace", children: [
2356
- /* @__PURE__ */ jsx32(MenuRow, { children: /* @__PURE__ */ jsx32("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
2357
- /* @__PURE__ */ jsx32(Note, { children: "Everyone on this relay shares this workspace, in every app." })
2569
+ relayUrl && /* @__PURE__ */ jsxs28(Fragment9, { children: [
2570
+ /* @__PURE__ */ jsx36(Divider, { className: "mx-0 my-2" }),
2571
+ /* @__PURE__ */ jsxs28(MenuSection, { label: "Workspace", children: [
2572
+ /* @__PURE__ */ jsx36(MenuRow, { children: /* @__PURE__ */ jsx36("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
2573
+ /* @__PURE__ */ jsx36(Note, { children: "Everyone on this relay shares this workspace, in every app." })
2358
2574
  ] })
2359
2575
  ] }),
2360
- appRows && /* @__PURE__ */ jsxs24(Fragment8, { children: [
2361
- /* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }),
2576
+ appRows && /* @__PURE__ */ jsxs28(Fragment9, { children: [
2577
+ /* @__PURE__ */ jsx36(Divider, { className: "mx-0 my-2" }),
2362
2578
  appRows
2363
2579
  ] }),
2364
- signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }) : null,
2365
- signedIn && idBase && /* @__PURE__ */ jsx32(
2580
+ signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx36(Divider, { className: "mx-0 my-2" }) : null,
2581
+ signedIn && idBase && /* @__PURE__ */ jsx36(
2366
2582
  MenuItem,
2367
2583
  {
2368
2584
  label: "Edit your profile in Estiva ID",
2369
2585
  onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
2370
2586
  }
2371
2587
  ),
2372
- onCopyKey && /* @__PURE__ */ jsx32(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2373
- idBase && onSignOut && /* @__PURE__ */ jsx32(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2588
+ onCopyKey && /* @__PURE__ */ jsx36(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2589
+ idBase && onSignOut && /* @__PURE__ */ jsx36(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2374
2590
  ] });
2375
2591
  }
2376
2592
  function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
2377
- const actions = useRef6(null);
2593
+ const actions = useRef7(null);
2378
2594
  const close = useCallback2(() => actions.current?.close(), []);
2379
2595
  return (
2380
2596
  /* The wrapper carries the caller's `className` and nothing else. It used
2381
2597
  to be `relative`, because the panel was positioned against it; the panel
2382
2598
  hangs from the trigger and portals now, so a positioning context here
2383
2599
  would only be a lie about what this box does. */
2384
- /* @__PURE__ */ jsx32("div", { className, children: /* @__PURE__ */ jsx32(
2600
+ /* @__PURE__ */ jsx36("div", { className, children: /* @__PURE__ */ jsx36(
2385
2601
  Menu,
2386
2602
  {
2387
2603
  align: "right",
2388
2604
  actionsRef: actions,
2389
2605
  className: "w-72",
2390
- trigger: /* @__PURE__ */ jsx32(
2606
+ trigger: /* @__PURE__ */ jsx36(
2391
2607
  PersonTrigger,
2392
2608
  {
2393
2609
  name: me.name,
@@ -2398,7 +2614,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2398
2614
  "aria-label": compact ? "Account menu" : void 0
2399
2615
  }
2400
2616
  ),
2401
- children: /* @__PURE__ */ jsx32(
2617
+ children: /* @__PURE__ */ jsx36(
2402
2618
  IdentityRows,
2403
2619
  {
2404
2620
  me,
@@ -2416,14 +2632,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2416
2632
  );
2417
2633
  }
2418
2634
  function Note({ children }) {
2419
- return /* @__PURE__ */ jsx32("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2635
+ return /* @__PURE__ */ jsx36("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2420
2636
  }
2421
2637
 
2422
2638
  // src/FilePicker.tsx
2423
2639
  import { forwardRef } from "react";
2424
- import { jsx as jsx33 } from "react/jsx-runtime";
2640
+ import { jsx as jsx37 } from "react/jsx-runtime";
2425
2641
  var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
2426
- return /* @__PURE__ */ jsx33(
2642
+ return /* @__PURE__ */ jsx37(
2427
2643
  "input",
2428
2644
  {
2429
2645
  ref,
@@ -2442,9 +2658,9 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
2442
2658
  });
2443
2659
 
2444
2660
  // src/Select.tsx
2445
- import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
2661
+ import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
2446
2662
  import { Select as BaseSelect } from "@base-ui/react/select";
2447
- import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
2663
+ import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
2448
2664
  var GAP4 = 4;
2449
2665
  var VIEWPORT_PAD4 = 8;
2450
2666
  function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
@@ -2452,7 +2668,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2452
2668
  const held = Boolean(disabledReason);
2453
2669
  const trigger = (
2454
2670
  // @estiva-escape(no-copied-look): N1 (Katerina, 24 September: record only): Select's box drops the hover while held, so it cannot take FIELD_SHELL_CLASSES as it is
2455
- /* @__PURE__ */ jsxs25(
2671
+ /* @__PURE__ */ jsxs29(
2456
2672
  BaseSelect.Trigger,
2457
2673
  {
2458
2674
  "aria-label": ariaLabel,
@@ -2485,21 +2701,21 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2485
2701
  className
2486
2702
  ),
2487
2703
  children: [
2488
- /* @__PURE__ */ jsxs25("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
2489
- selected?.leading && /* @__PURE__ */ jsx34("span", { className: "flex shrink-0 items-center", children: selected.leading }),
2490
- /* @__PURE__ */ jsx34(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
2704
+ /* @__PURE__ */ jsxs29("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
2705
+ selected?.leading && /* @__PURE__ */ jsx38("span", { className: "flex shrink-0 items-center", children: selected.leading }),
2706
+ /* @__PURE__ */ jsx38(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
2491
2707
  ] }),
2492
- /* @__PURE__ */ jsx34(
2708
+ /* @__PURE__ */ jsx38(
2493
2709
  BaseSelect.Icon,
2494
2710
  {
2495
- render: /* @__PURE__ */ jsx34(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2711
+ render: /* @__PURE__ */ jsx38(IconChevronDown3, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2496
2712
  }
2497
2713
  )
2498
2714
  ]
2499
2715
  }
2500
2716
  )
2501
2717
  );
2502
- return /* @__PURE__ */ jsxs25(
2718
+ return /* @__PURE__ */ jsxs29(
2503
2719
  BaseSelect.Root,
2504
2720
  {
2505
2721
  value,
@@ -2511,8 +2727,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2511
2727
  disabled: disabled && !held,
2512
2728
  modal: false,
2513
2729
  children: [
2514
- held ? /* @__PURE__ */ jsx34(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2515
- /* @__PURE__ */ jsx34(BaseSelect.Portal, { children: /* @__PURE__ */ jsx34(
2730
+ held ? /* @__PURE__ */ jsx38(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2731
+ /* @__PURE__ */ jsx38(BaseSelect.Portal, { children: /* @__PURE__ */ jsx38(
2516
2732
  BaseSelect.Positioner,
2517
2733
  {
2518
2734
  side: "bottom",
@@ -2521,25 +2737,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2521
2737
  collisionPadding: VIEWPORT_PAD4,
2522
2738
  alignItemWithTrigger: false,
2523
2739
  className: "z-50 data-[anchor-hidden]:hidden",
2524
- children: /* @__PURE__ */ jsx34(
2740
+ children: /* @__PURE__ */ jsx38(
2525
2741
  BaseSelect.Popup,
2526
2742
  {
2527
- render: /* @__PURE__ */ jsx34(MenuPanel, {}),
2743
+ render: /* @__PURE__ */ jsx38(MenuPanel, {}),
2528
2744
  className: "min-w-[var(--anchor-width)] p-0",
2529
- children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col gap-0.5 p-2", children: options.map((option) => /* @__PURE__ */ jsxs25(
2745
+ children: /* @__PURE__ */ jsx38(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col gap-0.5 p-2", children: options.map((option) => /* @__PURE__ */ jsxs29(
2530
2746
  BaseSelect.Item,
2531
2747
  {
2532
2748
  value: option.value,
2533
2749
  className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
2534
2750
  children: [
2535
- /* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 items-center gap-2", children: [
2536
- option.leading && /* @__PURE__ */ jsx34("span", { className: "flex shrink-0 items-center", children: option.leading }),
2537
- /* @__PURE__ */ jsx34(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
2751
+ /* @__PURE__ */ jsxs29("span", { className: "flex min-w-0 items-center gap-2", children: [
2752
+ option.leading && /* @__PURE__ */ jsx38("span", { className: "flex shrink-0 items-center", children: option.leading }),
2753
+ /* @__PURE__ */ jsx38(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
2538
2754
  ] }),
2539
- /* @__PURE__ */ jsx34(
2755
+ /* @__PURE__ */ jsx38(
2540
2756
  BaseSelect.ItemIndicator,
2541
2757
  {
2542
- render: /* @__PURE__ */ jsx34(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2758
+ render: /* @__PURE__ */ jsx38(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2543
2759
  }
2544
2760
  )
2545
2761
  ]
@@ -2558,9 +2774,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2558
2774
  // src/TextInput.tsx
2559
2775
  import { forwardRef as forwardRef2 } from "react";
2560
2776
  import { Input } from "@base-ui/react/input";
2561
- import { jsx as jsx35 } from "react/jsx-runtime";
2777
+ import { jsx as jsx39 } from "react/jsx-runtime";
2562
2778
  var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
2563
- return /* @__PURE__ */ jsx35(
2779
+ return /* @__PURE__ */ jsx39(
2564
2780
  Input,
2565
2781
  {
2566
2782
  ref,
@@ -2586,13 +2802,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
2586
2802
  // src/Textarea.tsx
2587
2803
  import { forwardRef as forwardRef3 } from "react";
2588
2804
  import { Field as BaseField3 } from "@base-ui/react/field";
2589
- import { jsx as jsx36 } from "react/jsx-runtime";
2805
+ import { jsx as jsx40 } from "react/jsx-runtime";
2590
2806
  var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2591
- return /* @__PURE__ */ jsx36(
2807
+ return /* @__PURE__ */ jsx40(
2592
2808
  BaseField3.Control,
2593
2809
  {
2594
2810
  ref,
2595
- render: /* @__PURE__ */ jsx36("textarea", {}),
2811
+ render: /* @__PURE__ */ jsx40("textarea", {}),
2596
2812
  className: cn(
2597
2813
  // The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
2598
2814
  // "aren't there hover states in text input and text area?"). Focus comes after hover in
@@ -2611,108 +2827,10 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2611
2827
  });
2612
2828
 
2613
2829
  // src/ConfirmDialog.tsx
2614
- import { useState as useState5 } from "react";
2615
-
2616
- // src/DialogShell.tsx
2617
- import { useRef as useRef7 } from "react";
2618
- import { Dialog as Dialog3 } from "@base-ui/react/dialog";
2619
- import { AlertDialog } from "@base-ui/react/alert-dialog";
2620
- import { IconX as IconX5 } from "@tabler/icons-react";
2621
-
2622
- // src/ContainerHeader.tsx
2623
- import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
2624
- import { Button as BaseButton6 } from "@base-ui/react/button";
2625
- import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
2626
- function ContainerHeader({ title, chevron = false, titleMenu, actions, className }) {
2627
- const text = typeof title === "string";
2628
- const name = /* @__PURE__ */ jsxs26("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
2629
- text ? /* @__PURE__ */ jsx37("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx37("div", { className: "min-w-0 flex-1", children: title }),
2630
- (chevron || titleMenu != null) && /* @__PURE__ */ jsx37(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2631
- ] });
2632
- return (
2633
- // With a title menu the bar gives the button 6px of its left padding
2634
- // (pl-3.5 + the button's px-1.5 = pl-5): the words stay where a title's
2635
- // are, and the fill is inside the bar — a negative margin had it clipped
2636
- // (Katerina, 5 October).
2637
- /* @__PURE__ */ jsxs26("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4", titleMenu != null ? "pl-3.5" : "pl-5", className), children: [
2638
- /* @__PURE__ */ jsx37("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: titleMenu != null ? /* @__PURE__ */ jsx37(
2639
- Menu,
2640
- {
2641
- trigger: /* @__PURE__ */ jsx37(BaseButton6, { type: "button", className: cn("flex min-w-0 items-center px-1.5 py-1", MENU_TRIGGER_CLASSES), children: name }),
2642
- children: titleMenu
2643
- }
2644
- ) : name }),
2645
- actions && /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
2646
- ] })
2647
- );
2648
- }
2649
-
2650
- // src/DialogShell.tsx
2651
- import { jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
2652
- function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
2653
- const Parts = alert ? AlertDialog : Dialog3;
2654
- const popupRef = useRef7(null);
2655
- return /* @__PURE__ */ jsx38(
2656
- Parts.Root,
2657
- {
2658
- open: true,
2659
- onOpenChange: (open) => {
2660
- if (!open) onClose();
2661
- },
2662
- children: /* @__PURE__ */ jsxs27(Parts.Portal, { children: [
2663
- /* @__PURE__ */ jsx38(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
2664
- /* @__PURE__ */ jsx38("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs27(
2665
- Parts.Popup,
2666
- {
2667
- ref: popupRef,
2668
- initialFocus: popupRef,
2669
- "aria-label": headerContent != null ? title : void 0,
2670
- className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
2671
- style: { width },
2672
- children: [
2673
- /* @__PURE__ */ jsx38(
2674
- ContainerHeader,
2675
- {
2676
- title: headerContent ?? /* @__PURE__ */ jsx38(Parts.Title, { className: "block truncate text-h4 text-text-primary", render: /* @__PURE__ */ jsx38("span", {}), children: title }),
2677
- actions: (
2678
- /*
2679
- The ✕ IS the `Close` part now, rather than a button that calls
2680
- `onClose` beside one (stage 4, 2026-09-07). Stage 3 could not do
2681
- this: an `IconButton` carrying a `tooltip` returned the tooltip
2682
- wrapper `<div>` as its root, so the part composed onto the
2683
- wrapper and not the button. Porting Tooltip removed the wrapper
2684
- — the trigger is the button itself — and the composition works.
2685
-
2686
- What it buys: the dialog closes through its own state machine,
2687
- so the ✕, Escape and the outside press are one path with one
2688
- reason attached, instead of one of the three going around.
2689
- */
2690
- /* @__PURE__ */ jsx38(
2691
- Parts.Close,
2692
- {
2693
- render: /* @__PURE__ */ jsx38(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx38(IconX5, { size: 16, stroke: 1.5 }) })
2694
- }
2695
- )
2696
- )
2697
- }
2698
- ),
2699
- bodyMaxHeight ? (
2700
- // The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
2701
- /* @__PURE__ */ jsx38("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx38(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
2702
- ) : /* @__PURE__ */ jsx38("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
2703
- footer != null && /* @__PURE__ */ jsx38("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
2704
- ]
2705
- }
2706
- ) })
2707
- ] })
2708
- }
2709
- );
2710
- }
2711
-
2712
- // src/ConfirmDialog.tsx
2713
- import { Fragment as Fragment9, jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
2830
+ import { useState as useState6 } from "react";
2831
+ import { Fragment as Fragment10, jsx as jsx41, jsxs as jsxs30 } from "react/jsx-runtime";
2714
2832
  function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
2715
- const [busy, setBusy] = useState5(false);
2833
+ const [busy, setBusy] = useState6(false);
2716
2834
  const confirm = async () => {
2717
2835
  setBusy(true);
2718
2836
  try {
@@ -2722,30 +2840,30 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
2722
2840
  setBusy(false);
2723
2841
  }
2724
2842
  };
2725
- return /* @__PURE__ */ jsx39(
2843
+ return /* @__PURE__ */ jsx41(
2726
2844
  DialogShell,
2727
2845
  {
2728
2846
  alert: true,
2729
2847
  title,
2730
2848
  onClose,
2731
- footer: /* @__PURE__ */ jsxs28(Fragment9, { children: [
2732
- /* @__PURE__ */ jsx39(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2733
- /* @__PURE__ */ jsx39(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2849
+ footer: /* @__PURE__ */ jsxs30(Fragment10, { children: [
2850
+ /* @__PURE__ */ jsx41(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2851
+ /* @__PURE__ */ jsx41(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2734
2852
  ] }),
2735
- children: /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2853
+ children: /* @__PURE__ */ jsx41("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2736
2854
  }
2737
2855
  );
2738
2856
  }
2739
2857
 
2740
2858
  // src/EditableText.tsx
2741
- import { useEffect as useEffect4, useRef as useRef8, useState as useState6 } from "react";
2859
+ import { useEffect as useEffect4, useRef as useRef8, useState as useState7 } from "react";
2742
2860
  import { Field as BaseField4 } from "@base-ui/react/field";
2743
2861
  import { Input as Input2 } from "@base-ui/react/input";
2744
- import { jsx as jsx40 } from "react/jsx-runtime";
2862
+ import { jsx as jsx42 } from "react/jsx-runtime";
2745
2863
  function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
2746
- const [editing, setEditing] = useState6(false);
2747
- const [draft, setDraft] = useState6(value);
2748
- const [busy, setBusy] = useState6(false);
2864
+ const [editing, setEditing] = useState7(false);
2865
+ const [draft, setDraft] = useState7(value);
2866
+ const [busy, setBusy] = useState7(false);
2749
2867
  const fieldRef = useRef8(null);
2750
2868
  useEffect4(() => {
2751
2869
  if (editing) {
@@ -2799,7 +2917,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2799
2917
  written and never read. Read-only, this is a line of text: whatever
2800
2918
  names the region around it (a `Field`, a `Property`) names this too.
2801
2919
  */
2802
- /* @__PURE__ */ jsx40(
2920
+ /* @__PURE__ */ jsx42(
2803
2921
  "div",
2804
2922
  {
2805
2923
  className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
@@ -2809,11 +2927,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2809
2927
  );
2810
2928
  }
2811
2929
  if (editing) {
2812
- return multiline ? /* @__PURE__ */ jsx40(
2930
+ return multiline ? /* @__PURE__ */ jsx42(
2813
2931
  BaseField4.Control,
2814
2932
  {
2815
2933
  ref: fieldRef,
2816
- render: /* @__PURE__ */ jsx40("textarea", { rows: 4 }),
2934
+ render: /* @__PURE__ */ jsx42("textarea", { rows: 4 }),
2817
2935
  "aria-label": label,
2818
2936
  value: draft,
2819
2937
  disabled: busy,
@@ -2822,7 +2940,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2822
2940
  onBlur: () => void commit(),
2823
2941
  className: fieldClass
2824
2942
  }
2825
- ) : /* @__PURE__ */ jsx40(
2943
+ ) : /* @__PURE__ */ jsx42(
2826
2944
  Input2,
2827
2945
  {
2828
2946
  ref: fieldRef,
@@ -2836,7 +2954,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2836
2954
  }
2837
2955
  );
2838
2956
  }
2839
- return /* @__PURE__ */ jsx40(
2957
+ return /* @__PURE__ */ jsx42(
2840
2958
  "button",
2841
2959
  {
2842
2960
  type: "button",
@@ -2856,7 +2974,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2856
2974
  // src/ErrorBoundary.tsx
2857
2975
  import { Component } from "react";
2858
2976
  import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
2859
- import { jsx as jsx41 } from "react/jsx-runtime";
2977
+ import { jsx as jsx43 } from "react/jsx-runtime";
2860
2978
  var ErrorBoundary = class extends Component {
2861
2979
  state = { hasError: false };
2862
2980
  static getDerivedStateFromError() {
@@ -2867,22 +2985,22 @@ var ErrorBoundary = class extends Component {
2867
2985
  }
2868
2986
  render() {
2869
2987
  if (!this.state.hasError) return this.props.children;
2870
- const message = /* @__PURE__ */ jsx41(
2988
+ const message = /* @__PURE__ */ jsx43(
2871
2989
  EmptyState,
2872
2990
  {
2873
- icon: /* @__PURE__ */ jsx41(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
2991
+ icon: /* @__PURE__ */ jsx43(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
2874
2992
  message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
2875
2993
  action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
2876
2994
  }
2877
2995
  );
2878
2996
  if (this.props.frame) return this.props.frame(message);
2879
- return this.props.fallbackClassName ? /* @__PURE__ */ jsx41("div", { className: this.props.fallbackClassName, children: message }) : message;
2997
+ return this.props.fallbackClassName ? /* @__PURE__ */ jsx43("div", { className: this.props.fallbackClassName, children: message }) : message;
2880
2998
  }
2881
2999
  };
2882
3000
 
2883
3001
  // src/ProgressBar.tsx
2884
3002
  import { Progress } from "@base-ui/react/progress";
2885
- import { jsx as jsx42 } from "react/jsx-runtime";
3003
+ import { jsx as jsx44 } from "react/jsx-runtime";
2886
3004
  var TRACK_CLASSES = {
2887
3005
  default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
2888
3006
  // 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
@@ -2895,17 +3013,17 @@ var INDICATOR_CLASSES = {
2895
3013
  function ProgressBar({ value, max, label, variant = "default", className }) {
2896
3014
  return (
2897
3015
  // `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
2898
- /* @__PURE__ */ jsx42(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx42(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx42(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
3016
+ /* @__PURE__ */ jsx44(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx44(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx44(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
2899
3017
  );
2900
3018
  }
2901
3019
 
2902
3020
  // src/Breadcrumb.tsx
2903
- import { Fragment as Fragment10, useCallback as useCallback3, useLayoutEffect as useLayoutEffect4, useRef as useRef9, useState as useState7 } from "react";
2904
- import { jsx as jsx43, jsxs as jsxs29 } from "react/jsx-runtime";
3021
+ import { Fragment as Fragment11, useCallback as useCallback3, useLayoutEffect as useLayoutEffect4, useRef as useRef9, useState as useState8 } from "react";
3022
+ import { jsx as jsx45, jsxs as jsxs31 } from "react/jsx-runtime";
2905
3023
  function Breadcrumb({ items, className }) {
2906
3024
  const navRef = useRef9(null);
2907
3025
  const labelRefs = useRef9([]);
2908
- const [truncated, setTruncated] = useState7(/* @__PURE__ */ new Set());
3026
+ const [truncated, setTruncated] = useState8(/* @__PURE__ */ new Set());
2909
3027
  const measure = useCallback3(() => {
2910
3028
  const next = /* @__PURE__ */ new Set();
2911
3029
  labelRefs.current.forEach((el, index) => {
@@ -2921,7 +3039,7 @@ function Breadcrumb({ items, className }) {
2921
3039
  observer.observe(nav);
2922
3040
  return () => observer.disconnect();
2923
3041
  }, [measure, items]);
2924
- return /* @__PURE__ */ jsx43("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) => {
3042
+ return /* @__PURE__ */ jsx45("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) => {
2925
3043
  const last = index === items.length - 1;
2926
3044
  const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
2927
3045
  const text = cn(
@@ -2942,34 +3060,34 @@ function Breadcrumb({ items, className }) {
2942
3060
  // on a box around it, which the link takes them from, rather than
2943
3061
  // pushed into it (UIG-9); the link is still the one element that
2944
3062
  // truncates and is measured.
2945
- /* @__PURE__ */ jsx43("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx43(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
2946
- ) : /* @__PURE__ */ jsx43("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
2947
- return /* @__PURE__ */ jsxs29(Fragment10, { children: [
2948
- index > 0 && /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
2949
- item.icon && /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
3063
+ /* @__PURE__ */ jsx45("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx45(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
3064
+ ) : /* @__PURE__ */ jsx45("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
3065
+ return /* @__PURE__ */ jsxs31(Fragment11, { children: [
3066
+ index > 0 && /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
3067
+ item.icon && /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
2950
3068
  truncated.has(index) ? (
2951
3069
  // `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
2952
3070
  // must keep truncating inside it, or wrapping it would widen the
2953
3071
  // trail and the tooltip would never be needed again.
2954
- /* @__PURE__ */ jsx43(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
3072
+ /* @__PURE__ */ jsx45(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
2955
3073
  ) : crumb
2956
3074
  ] }, `${item.label}-${index}`);
2957
3075
  }) });
2958
3076
  }
2959
3077
 
2960
3078
  // src/NavItem.tsx
2961
- import { useId, useState as useState8 } from "react";
3079
+ import { useId as useId2, useState as useState9 } from "react";
2962
3080
  import { Collapsible } from "@base-ui/react/collapsible";
2963
3081
  import { IconAlertSquareRounded, IconChevronRight as IconChevronRight2, IconDotsVertical } from "@tabler/icons-react";
2964
3082
 
2965
3083
  // src/UnreadDot.tsx
2966
- import { jsx as jsx44 } from "react/jsx-runtime";
3084
+ import { jsx as jsx46 } from "react/jsx-runtime";
2967
3085
  function UnreadDot({ className }) {
2968
- return /* @__PURE__ */ jsx44("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx44("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
3086
+ return /* @__PURE__ */ jsx46("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx46("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
2969
3087
  }
2970
3088
 
2971
3089
  // src/NavItem.tsx
2972
- import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
3090
+ import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
2973
3091
  function NavItem({
2974
3092
  label,
2975
3093
  href,
@@ -2989,8 +3107,8 @@ function NavItem({
2989
3107
  className,
2990
3108
  ...props
2991
3109
  }) {
2992
- const [openState, setOpenState] = useState8(defaultOpen);
2993
- const panelId = useId();
3110
+ const [openState, setOpenState] = useState9(defaultOpen);
3111
+ const panelId = useId2();
2994
3112
  const hasRows = children != null && children !== false;
2995
3113
  const open = openProp ?? openState;
2996
3114
  const setOpen = (next) => {
@@ -2998,9 +3116,9 @@ function NavItem({
2998
3116
  onOpenChange?.(next);
2999
3117
  };
3000
3118
  const besides = menu != null || hasRows;
3001
- const mark = unread ? urgent ? /* @__PURE__ */ jsx45(UrgentMark, {}) : /* @__PURE__ */ jsx45(UnreadDot, {}) : null;
3119
+ const mark = unread ? urgent ? /* @__PURE__ */ jsx47(UrgentMark, {}) : /* @__PURE__ */ jsx47(UnreadDot, {}) : null;
3002
3120
  const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-has-[:focus-visible]/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0 [@media(hover:none)]:opacity-0";
3003
- const row = /* @__PURE__ */ jsxs30(
3121
+ const row = /* @__PURE__ */ jsxs32(
3004
3122
  "a",
3005
3123
  {
3006
3124
  href,
@@ -3021,7 +3139,7 @@ function NavItem({
3021
3139
  ),
3022
3140
  ...props,
3023
3141
  children: [
3024
- (icon || hasRows) && /* @__PURE__ */ jsx45(
3142
+ (icon || hasRows) && /* @__PURE__ */ jsx47(
3025
3143
  "span",
3026
3144
  {
3027
3145
  className: cn(
@@ -3032,14 +3150,15 @@ function NavItem({
3032
3150
  children: icon
3033
3151
  }
3034
3152
  ),
3035
- /* @__PURE__ */ jsx45("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
3153
+ /* @__PURE__ */ jsx47("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
3036
3154
  hint != null && // Takes room only while it shows, so the label gives way to it.
3037
- /* @__PURE__ */ jsx45("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-has-[:focus-visible]/nav:flex", children: hint }),
3038
- count ? /* @__PURE__ */ jsx45(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx45(
3155
+ /* @__PURE__ */ jsx47("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-has-[:focus-visible]/nav:flex", children: hint }),
3156
+ count ? /* @__PURE__ */ jsx47(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx47(
3039
3157
  "span",
3040
3158
  {
3041
3159
  className: cn(
3042
- "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted",
3160
+ "min-w-4 shrink-0 text-center",
3161
+ COUNT_TEXT_CLASSES,
3043
3162
  // With a menu and no mark after it, the ⋮ takes this place while it shows.
3044
3163
  !mark && stepsAside
3045
3164
  ),
@@ -3050,7 +3169,7 @@ function NavItem({
3050
3169
  // `-mr-1`: the 24px slot's dot then sits on the axis of a count and
3051
3170
  // of the ⋮ (8px from the edge to the 16px box), one column with a
3052
3171
  // folder heading's dot and ⋮ (Katerina, 5 October).
3053
- /* @__PURE__ */ jsx45("span", { className: cn("-mr-1 flex shrink-0", stepsAside), children: mark })
3172
+ /* @__PURE__ */ jsx47("span", { className: cn("-mr-1 flex shrink-0", stepsAside), children: mark })
3054
3173
  ) : menu != null && !count ? (
3055
3174
  // Nothing at the right, but a menu: no room is kept at rest, so the
3056
3175
  // label has the row's whole width; while the ⋮ shows, its 24px slot
@@ -3058,18 +3177,18 @@ function NavItem({
3058
3177
  // `-mr-1`: the ⋮ sits at `right-1`, 4px into the row's padding, so the
3059
3178
  // slot does too — at the padding's edge it kept 4px the ⋮ never
3060
3179
  // covers, and the label stopped 12px short of the button, not 8.
3061
- /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "-mr-1 hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block [@media(hover:none)]:block" })
3180
+ /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: "-mr-1 hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block [@media(hover:none)]:block" })
3062
3181
  ) : null
3063
3182
  ]
3064
3183
  }
3065
3184
  );
3066
3185
  if (!besides && hint == null) return row;
3067
3186
  const name = menuLabel ?? `More options for ${label}`;
3068
- const line = /* @__PURE__ */ jsxs30("div", { className: "group/nav relative shrink-0", children: [
3187
+ const line = /* @__PURE__ */ jsxs32("div", { className: "group/nav relative shrink-0", children: [
3069
3188
  row,
3070
3189
  hasRows && // `left-1`: the 24px button's 16px arrow then sits where the icon
3071
3190
  // sits (the row's px-2), so the icon turns into the arrow in place.
3072
- /* @__PURE__ */ jsx45("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100", children: /* @__PURE__ */ jsx45(
3191
+ /* @__PURE__ */ jsx47("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100", children: /* @__PURE__ */ jsx47(
3073
3192
  IconButton,
3074
3193
  {
3075
3194
  tooltip: open ? "Collapse" : "Expand",
@@ -3077,7 +3196,7 @@ function NavItem({
3077
3196
  "aria-expanded": open,
3078
3197
  "aria-controls": panelId,
3079
3198
  onClick: () => setOpen(!open),
3080
- children: /* @__PURE__ */ jsx45(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
3199
+ children: /* @__PURE__ */ jsx47(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
3081
3200
  }
3082
3201
  ) }),
3083
3202
  menu != null && // `right-1`: the 24px button's 16px icon ends 8px from the row's
@@ -3088,61 +3207,61 @@ function NavItem({
3088
3207
  // right of the slot's centre.
3089
3208
  // On a screen with no hover it always shows: nothing there can point
3090
3209
  // at the row, and the menu has no other way in.
3091
- /* @__PURE__ */ jsx45("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100"), children: /* @__PURE__ */ jsx45(
3210
+ /* @__PURE__ */ jsx47("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100"), children: /* @__PURE__ */ jsx47(
3092
3211
  Menu,
3093
3212
  {
3094
3213
  align: "right",
3095
- trigger: /* @__PURE__ */ jsx45(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx45(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
3214
+ trigger: /* @__PURE__ */ jsx47(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx47(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
3096
3215
  children: menu
3097
3216
  }
3098
3217
  ) })
3099
3218
  ] });
3100
3219
  if (!hasRows) return line;
3101
- return /* @__PURE__ */ jsxs30(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
3220
+ return /* @__PURE__ */ jsxs32(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
3102
3221
  line,
3103
- /* @__PURE__ */ jsx45(
3222
+ /* @__PURE__ */ jsx47(
3104
3223
  Collapsible.Panel,
3105
3224
  {
3106
3225
  id: panelId,
3107
3226
  hiddenUntilFound: true,
3108
3227
  className: COLLAPSIBLE_PANEL_CLASSES,
3109
- children: /* @__PURE__ */ jsx45("div", { className: "flex flex-col gap-0.5 pt-0.5 pl-6", children })
3228
+ children: /* @__PURE__ */ jsx47("div", { className: "flex flex-col gap-0.5 pt-0.5 pl-6", children })
3110
3229
  }
3111
3230
  )
3112
3231
  ] });
3113
3232
  }
3114
3233
  function UrgentMark() {
3115
- return /* @__PURE__ */ jsx45("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx45("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx45(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
3234
+ return /* @__PURE__ */ jsx47("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx47("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx47(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
3116
3235
  }
3117
3236
 
3118
3237
  // src/NavTree.tsx
3119
3238
  import { useEffect as useEffect5, useRef as useRef10 } from "react";
3120
3239
 
3121
3240
  // src/CollapsibleSection.tsx
3122
- import { useState as useState9 } from "react";
3241
+ import { useState as useState10 } from "react";
3123
3242
  import { Collapsible as Collapsible2 } from "@base-ui/react/collapsible";
3124
3243
 
3125
3244
  // src/SectionHeader.tsx
3126
3245
  import { IconChevronRight as IconChevronRight3, IconDotsVertical as IconDotsVertical2 } from "@tabler/icons-react";
3127
3246
  import { useRender } from "@base-ui/react/use-render";
3128
- import { Fragment as Fragment11, jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
3129
- function SectionHeader({ title, chevron = false, icon, isExpanded = true, onToggle, trailing, actions, menu, menuLabel, showActions = "hover", hover = "fill", look = "heading", render, className }) {
3247
+ import { Fragment as Fragment12, jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
3248
+ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onToggle, trailing, count, actions, menu, menuLabel, showActions = "hover", hover = "fill", look = "heading", render, className }) {
3130
3249
  const row = look === "row";
3131
3250
  const acts = actions && actions.length > 0 || menu != null;
3132
3251
  const trailingClasses = !acts ? "has-[[data-unread]]:-mr-1" : showActions === "hover" && "has-[[data-unread]]:pointer-events-none has-[[data-unread]]:absolute has-[[data-unread]]:inset-y-0 has-[[data-unread]]:right-1 has-[[data-unread]]:w-6 has-[[data-unread]]:justify-center has-[[data-unread]]:transition-opacity group-hover:has-[[data-unread]]:opacity-0 group-has-[:focus-visible]:has-[[data-unread]]:opacity-0 group-has-[[data-section-menu]_[aria-expanded=true]]:has-[[data-unread]]:opacity-0 [@media(hover:none)]:has-[[data-unread]]:opacity-0";
3133
3252
  const reveal = showActions === "hover" && "opacity-0 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100";
3134
3253
  const titleElement = useRender({
3135
- render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
3254
+ render: render ?? (chevron ? /* @__PURE__ */ jsx48("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx48("span", {})),
3136
3255
  props: {
3137
3256
  // `text-left`: a button centres its text. `h-full` and `flex-1`: the
3138
3257
  // whole row up to the actions is the hit target, as it was when the
3139
3258
  // row itself carried the click.
3140
3259
  // An icon is a row's: NavItem's 8px after it.
3141
3260
  className: cn("flex h-full min-w-0 flex-1 items-center text-left", row || chevron || icon != null ? "gap-2" : "gap-1"),
3142
- children: /* @__PURE__ */ jsxs31(Fragment11, { children: [
3143
- icon != null ? /* @__PURE__ */ jsxs31("span", { className: "relative flex size-4 shrink-0 items-center justify-center text-text-secondary", children: [
3144
- /* @__PURE__ */ jsx46("span", { className: cn("flex", chevron && "transition-opacity group-hover:opacity-0 group-has-[:focus-visible]:opacity-0"), children: icon }),
3145
- chevron && /* @__PURE__ */ jsx46(
3261
+ children: /* @__PURE__ */ jsxs33(Fragment12, { children: [
3262
+ icon != null ? /* @__PURE__ */ jsxs33("span", { className: "relative flex size-4 shrink-0 items-center justify-center text-text-secondary", children: [
3263
+ /* @__PURE__ */ jsx48("span", { className: cn("flex", chevron && "transition-opacity group-hover:opacity-0 group-has-[:focus-visible]:opacity-0"), children: icon }),
3264
+ chevron && /* @__PURE__ */ jsx48(
3146
3265
  IconChevronRight3,
3147
3266
  {
3148
3267
  size: 16,
@@ -3150,7 +3269,7 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3150
3269
  className: cn("absolute opacity-0 transition-[opacity,transform] duration-150 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100", isExpanded && "rotate-90")
3151
3270
  }
3152
3271
  )
3153
- ] }) : chevron && /* @__PURE__ */ jsx46(
3272
+ ] }) : chevron && /* @__PURE__ */ jsx48(
3154
3273
  IconChevronRight3,
3155
3274
  {
3156
3275
  size: 16,
@@ -3158,14 +3277,15 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3158
3277
  className: cn("shrink-0 transition-transform duration-150", !row && "text-text-secondary", isExpanded && "rotate-90")
3159
3278
  }
3160
3279
  ),
3161
- look === "quiet" ? /* @__PURE__ */ jsx46("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
3280
+ look === "quiet" ? /* @__PURE__ */ jsx48("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
3162
3281
  // A row's words: NavItem's size and colour, brightening under the pointer with the row.
3163
- /* @__PURE__ */ jsx46("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
3164
- ) : /* @__PURE__ */ jsx46(SectionLabel, { folds: chevron, children: title })
3282
+ /* @__PURE__ */ jsx48("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
3283
+ ) : /* @__PURE__ */ jsx48(SectionLabel, { folds: chevron, children: title }),
3284
+ count != null && /* @__PURE__ */ jsx48("span", { className: cn("ml-1 shrink-0", COUNT_TEXT_CLASSES), children: count })
3165
3285
  ] })
3166
3286
  }
3167
3287
  });
3168
- return /* @__PURE__ */ jsxs31(
3288
+ return /* @__PURE__ */ jsxs33(
3169
3289
  "div",
3170
3290
  {
3171
3291
  className: cn(
@@ -3186,18 +3306,18 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3186
3306
  ),
3187
3307
  children: [
3188
3308
  titleElement,
3189
- trailing != null && /* @__PURE__ */ jsx46("div", { className: cn("flex shrink-0 items-center", trailingClasses), children: trailing }),
3190
- acts && /* @__PURE__ */ jsx46(
3309
+ trailing != null && /* @__PURE__ */ jsx48("div", { className: cn("flex shrink-0 items-center", trailingClasses), children: trailing }),
3310
+ acts && /* @__PURE__ */ jsx48(
3191
3311
  "div",
3192
3312
  {
3193
3313
  className: "-mr-1 flex shrink-0 items-center",
3194
- children: /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center gap-1", reveal), children: [
3195
- actions?.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3196
- menu != null && /* @__PURE__ */ jsx46("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx46(
3314
+ children: /* @__PURE__ */ jsxs33("div", { className: cn("flex items-center gap-1", reveal), children: [
3315
+ actions?.map((action) => /* @__PURE__ */ jsx48(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3316
+ menu != null && /* @__PURE__ */ jsx48("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx48(
3197
3317
  Menu,
3198
3318
  {
3199
3319
  align: "right",
3200
- trigger: /* @__PURE__ */ jsx46(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx46(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3320
+ trigger: /* @__PURE__ */ jsx48(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx48(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3201
3321
  children: menu
3202
3322
  }
3203
3323
  ) })
@@ -3210,7 +3330,7 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3210
3330
  }
3211
3331
 
3212
3332
  // src/CollapsibleSection.tsx
3213
- import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
3333
+ import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
3214
3334
  var OPEN = "open";
3215
3335
  var CLOSED = "closed";
3216
3336
  function readStored(key) {
@@ -3230,38 +3350,38 @@ function writeStored(key, open) {
3230
3350
  }
3231
3351
  }
3232
3352
  function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, icon, trailing, actions, menu, menuLabel, showActions, look = "heading", indent = false, children, className, contentClassName }) {
3233
- const [openState, setOpenState] = useState9(() => readStored(storageKey) ?? defaultOpen);
3353
+ const [openState, setOpenState] = useState10(() => readStored(storageKey) ?? defaultOpen);
3234
3354
  const open = openProp ?? openState;
3235
3355
  const setOpen = (next) => {
3236
3356
  setOpenState(next);
3237
3357
  writeStored(storageKey, next);
3238
3358
  onOpenChange?.(next);
3239
3359
  };
3240
- return /* @__PURE__ */ jsxs32(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
3241
- /* @__PURE__ */ jsx47(SectionHeader, { title, chevron: true, icon, isExpanded: open, trailing, actions, menu, menuLabel, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx47(Collapsible2.Trigger, {}) }),
3242
- /* @__PURE__ */ jsx47(
3360
+ return /* @__PURE__ */ jsxs34(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
3361
+ /* @__PURE__ */ jsx49(SectionHeader, { title, chevron: true, icon, isExpanded: open, trailing, actions, menu, menuLabel, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx49(Collapsible2.Trigger, {}) }),
3362
+ /* @__PURE__ */ jsx49(
3243
3363
  Collapsible2.Panel,
3244
3364
  {
3245
3365
  hiddenUntilFound: true,
3246
3366
  className: COLLAPSIBLE_PANEL_CLASSES,
3247
- children: /* @__PURE__ */ jsx47("div", { className: cn("flex flex-col pt-0.5", (look === "row" || indent) && "pl-6", contentClassName), children })
3367
+ children: /* @__PURE__ */ jsx49("div", { className: cn("flex flex-col pt-0.5", (look === "row" || indent) && "pl-6", contentClassName), children })
3248
3368
  }
3249
3369
  )
3250
3370
  ] });
3251
3371
  }
3252
3372
 
3253
3373
  // src/NavTree.tsx
3254
- import { Fragment as Fragment12, jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
3374
+ import { Fragment as Fragment13, jsx as jsx50, jsxs as jsxs35 } from "react/jsx-runtime";
3255
3375
  var NAV_TREE_INTENT_MS = 150;
3256
3376
  function holds(nodes, id) {
3257
3377
  return !!nodes && id !== void 0 && nodes.some((node) => node.id === id || holds(node.children ?? null, id));
3258
3378
  }
3259
3379
  function Line({ message }) {
3260
- return /* @__PURE__ */ jsx48("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx48(EmptyState, { scope: "section", message }) });
3380
+ return /* @__PURE__ */ jsx50("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx50(EmptyState, { scope: "section", message }) });
3261
3381
  }
3262
3382
  function Row({ node, selected, onSelect }) {
3263
- const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx48(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx48(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 2 }) : void 0;
3264
- return /* @__PURE__ */ jsx48(
3383
+ const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx50(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx50(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx50(SkeletonList, { rows: 2 }) : void 0;
3384
+ return /* @__PURE__ */ jsx50(
3265
3385
  NavItem,
3266
3386
  {
3267
3387
  href: node.href,
@@ -3283,7 +3403,7 @@ function Row({ node, selected, onSelect }) {
3283
3403
  );
3284
3404
  }
3285
3405
  function Group({ group, selected, onSelect, storageKey }) {
3286
- return /* @__PURE__ */ jsx48(
3406
+ return /* @__PURE__ */ jsx50(
3287
3407
  NavTreeSection,
3288
3408
  {
3289
3409
  id: group.id,
@@ -3299,7 +3419,7 @@ function Group({ group, selected, onSelect, storageKey }) {
3299
3419
  onOpenChange: group.onOpenChange,
3300
3420
  storageKey: storageKey ? `${storageKey}.${group.id}` : void 0,
3301
3421
  onIntent: group.onIntent,
3302
- children: group.nodes?.map((node) => /* @__PURE__ */ jsx48(Row, { node, selected, onSelect }, node.id))
3422
+ children: group.nodes?.map((node) => /* @__PURE__ */ jsx50(Row, { node, selected, onSelect }, node.id))
3303
3423
  }
3304
3424
  );
3305
3425
  }
@@ -3307,7 +3427,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3307
3427
  const timer = useRef10(void 0);
3308
3428
  useEffect5(() => () => clearTimeout(timer.current), []);
3309
3429
  const intent = onIntent;
3310
- return /* @__PURE__ */ jsx48(
3430
+ return /* @__PURE__ */ jsx50(
3311
3431
  "div",
3312
3432
  {
3313
3433
  className: "shrink-0 [&+&]:mt-1",
@@ -3318,7 +3438,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3318
3438
  } : void 0,
3319
3439
  onPointerLeave: intent ? () => clearTimeout(timer.current) : void 0,
3320
3440
  onFocus: intent,
3321
- children: /* @__PURE__ */ jsx48(
3441
+ children: /* @__PURE__ */ jsx50(
3322
3442
  CollapsibleSection,
3323
3443
  {
3324
3444
  title,
@@ -3333,26 +3453,26 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3333
3453
  icon,
3334
3454
  className: "shrink-0",
3335
3455
  contentClassName: "gap-0.5",
3336
- children: message !== void 0 ? /* @__PURE__ */ jsx48(Line, { message }) : loading ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 3 }) : children
3456
+ children: message !== void 0 ? /* @__PURE__ */ jsx50(Line, { message }) : loading ? /* @__PURE__ */ jsx50(SkeletonList, { rows: 3 }) : children
3337
3457
  }
3338
3458
  )
3339
3459
  }
3340
3460
  );
3341
3461
  }
3342
3462
  function NavTree({ title, titleActions, groups, children, selected, onSelect, emptyMessage = "", storageKey }) {
3343
- return /* @__PURE__ */ jsxs33(Fragment12, { children: [
3344
- title && /* @__PURE__ */ jsx48(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
3345
- groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
3463
+ return /* @__PURE__ */ jsxs35(Fragment13, { children: [
3464
+ title && /* @__PURE__ */ jsx50(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
3465
+ groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx50(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
3346
3466
  // No words, no line: an app that says nothing when it has no groups.
3347
- emptyMessage ? /* @__PURE__ */ jsx48(Line, { message: emptyMessage }) : null
3348
- ) : groups.map((group) => /* @__PURE__ */ jsx48(Group, { group, selected, onSelect, storageKey }, group.id))
3467
+ emptyMessage ? /* @__PURE__ */ jsx50(Line, { message: emptyMessage }) : null
3468
+ ) : groups.map((group) => /* @__PURE__ */ jsx50(Group, { group, selected, onSelect, storageKey }, group.id))
3349
3469
  ] });
3350
3470
  }
3351
3471
 
3352
3472
  // src/Popover.tsx
3353
3473
  import { useMemo as useMemo3 } from "react";
3354
3474
  import { Popover as BasePopover } from "@base-ui/react/popover";
3355
- import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
3475
+ import { jsx as jsx51, jsxs as jsxs36 } from "react/jsx-runtime";
3356
3476
  var GAP5 = 4;
3357
3477
  var VIEWPORT_PAD5 = 8;
3358
3478
  function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
@@ -3361,7 +3481,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3361
3481
  if (anchor instanceof Element) return anchor;
3362
3482
  return { getBoundingClientRect: () => anchor };
3363
3483
  }, [anchor]);
3364
- return /* @__PURE__ */ jsxs34(
3484
+ return /* @__PURE__ */ jsxs36(
3365
3485
  BasePopover.Root,
3366
3486
  {
3367
3487
  open,
@@ -3369,8 +3489,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3369
3489
  actionsRef,
3370
3490
  modal: false,
3371
3491
  children: [
3372
- trigger && /* @__PURE__ */ jsx49(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
3373
- /* @__PURE__ */ jsx49(BasePopover.Portal, { children: /* @__PURE__ */ jsx49(
3492
+ trigger && /* @__PURE__ */ jsx51(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
3493
+ /* @__PURE__ */ jsx51(BasePopover.Portal, { children: /* @__PURE__ */ jsx51(
3374
3494
  BasePopover.Positioner,
3375
3495
  {
3376
3496
  anchor: anchorTarget,
@@ -3379,20 +3499,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3379
3499
  sideOffset: GAP5,
3380
3500
  collisionPadding: VIEWPORT_PAD5,
3381
3501
  className: "z-50 data-[anchor-hidden]:hidden",
3382
- children: /* @__PURE__ */ jsx49(
3502
+ children: /* @__PURE__ */ jsx51(
3383
3503
  BasePopover.Popup,
3384
3504
  {
3385
3505
  "aria-label": ariaLabel,
3386
3506
  initialFocus: trigger ? void 0 : false,
3387
3507
  finalFocus,
3388
3508
  className: cn("min-w-[180px] outline-none p-0", className),
3389
- render: /* @__PURE__ */ jsx49(MenuPanel, {}),
3390
- children: /* @__PURE__ */ jsx49(
3509
+ render: /* @__PURE__ */ jsx51(MenuPanel, {}),
3510
+ children: /* @__PURE__ */ jsx51(
3391
3511
  ScrollArea,
3392
3512
  {
3393
3513
  viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
3394
3514
  contentClassName: cn("flex flex-col p-2", contentClassName),
3395
- children: /* @__PURE__ */ jsx49(DividerInPanel.Provider, { value: true, children })
3515
+ children: /* @__PURE__ */ jsx51(DividerInPanel.Provider, { value: true, children })
3396
3516
  }
3397
3517
  )
3398
3518
  }
@@ -3405,14 +3525,14 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3405
3525
  }
3406
3526
 
3407
3527
  // src/SuggestionMenu.tsx
3408
- import { useCallback as useCallback4, useEffect as useEffect6, useId as useId2, useImperativeHandle, useMemo as useMemo4, useRef as useRef11, useState as useState10 } from "react";
3409
- import { jsx as jsx50, jsxs as jsxs35 } from "react/jsx-runtime";
3528
+ import { useCallback as useCallback4, useEffect as useEffect6, useId as useId3, useImperativeHandle, useMemo as useMemo4, useRef as useRef11, useState as useState11 } from "react";
3529
+ import { jsx as jsx52, jsxs as jsxs37 } from "react/jsx-runtime";
3410
3530
  function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sections, itemKey, row, onSelect, handle }) {
3411
3531
  const shown = useMemo4(() => sections.filter((section) => section.items.length > 0), [sections]);
3412
3532
  const items = useMemo4(() => shown.flatMap((section) => section.items), [shown]);
3413
3533
  const keys = items.map(itemKey).join("\n");
3414
- const [highlight, setHighlight] = useState10(0);
3415
- const base = useId2();
3534
+ const [highlight, setHighlight] = useState11(0);
3535
+ const base = useId3();
3416
3536
  const listboxId = `${base}-list`;
3417
3537
  const chosen = useRef11(null);
3418
3538
  useEffect6(() => void (chosen.current = highlight > 0 ? keys.split("\n")[highlight] ?? null : null), [highlight]);
@@ -3471,7 +3591,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3471
3591
  const { label, description, leading, shortcut, hint, size } = row(item);
3472
3592
  return (
3473
3593
  // A row of a list the editor drives from its caret: focus stays in the text, so the row is no Tab stop.
3474
- /* @__PURE__ */ jsx50(
3594
+ /* @__PURE__ */ jsx52(
3475
3595
  MenuItem,
3476
3596
  {
3477
3597
  role: "option",
@@ -3498,18 +3618,47 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3498
3618
  };
3499
3619
  return (
3500
3620
  // finalFocus={false}: focus never left the text, and a list that closes because focus moved elsewhere must not pull it back (71a4577b).
3501
- /* @__PURE__ */ jsx50(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, finalFocus: false, children: /* @__PURE__ */ jsx50("div", { ref: keepFocus, id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col gap-0.5", children: shown.map((section, i) => /* @__PURE__ */ jsxs35("div", { className: "contents", children: [
3502
- i > 0 && /* @__PURE__ */ jsx50(MenuSeparator, {}),
3503
- section.label ? /* @__PURE__ */ jsx50("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx50(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
3621
+ /* @__PURE__ */ jsx52(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, finalFocus: false, children: /* @__PURE__ */ jsx52("div", { ref: keepFocus, id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col gap-0.5", children: shown.map((section, i) => /* @__PURE__ */ jsxs37("div", { className: "contents", children: [
3622
+ i > 0 && /* @__PURE__ */ jsx52(MenuSeparator, {}),
3623
+ section.label ? /* @__PURE__ */ jsx52("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx52(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
3504
3624
  ] }, section.label ?? i)) }) })
3505
3625
  );
3506
3626
  }
3507
3627
 
3628
+ // src/ShowMore.tsx
3629
+ import { useLayoutEffect as useLayoutEffect5, useRef as useRef12, useState as useState12 } from "react";
3630
+ import { jsx as jsx53, jsxs as jsxs38 } from "react/jsx-runtime";
3631
+ var FADE_CLASSES = { surface: "from-bg-surface", inset: "from-bg-inset" };
3632
+ function ShowMore({ children, maxHeight = 96, surface = "surface", className }) {
3633
+ const box = useRef12(null);
3634
+ const [open, setOpen] = useState12(false);
3635
+ const [overflows, setOverflows] = useState12(false);
3636
+ useLayoutEffect5(() => {
3637
+ const el = box.current;
3638
+ if (!el) return;
3639
+ const measure = () => setOverflows(el.scrollHeight > maxHeight + 1);
3640
+ measure();
3641
+ if (typeof ResizeObserver === "undefined") return;
3642
+ const observer = new ResizeObserver(measure);
3643
+ observer.observe(el);
3644
+ return () => observer.disconnect();
3645
+ }, [maxHeight]);
3646
+ const cut = overflows && !open;
3647
+ return /* @__PURE__ */ jsxs38("div", { className: cn("flex flex-col items-start", className), children: [
3648
+ /* @__PURE__ */ jsxs38("div", { ref: box, className: cn("relative w-full", cut && "overflow-hidden"), style: cut ? { maxHeight } : void 0, onFocus: cut ? () => setOpen(true) : void 0, children: [
3649
+ children,
3650
+ cut && /* @__PURE__ */ jsx53("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-x-0 bottom-0 h-10 bg-gradient-to-t to-transparent", FADE_CLASSES[surface]) })
3651
+ ] }),
3652
+ overflows && // `-ml-1.5`: the small button's own 6px inset, so its words start where the content's do.
3653
+ /* @__PURE__ */ jsx53(Button, { variant: "muted", size: "small", className: "-ml-1.5 mt-1", "aria-expanded": open, onClick: () => setOpen((o) => !o), children: open ? "Show less" : "Show more" })
3654
+ ] });
3655
+ }
3656
+
3508
3657
  // src/Toolbar.tsx
3509
3658
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
3510
- import { jsx as jsx51 } from "react/jsx-runtime";
3659
+ import { jsx as jsx54 } from "react/jsx-runtime";
3511
3660
  function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
3512
- const strip = /* @__PURE__ */ jsx51(
3661
+ const strip = /* @__PURE__ */ jsx54(
3513
3662
  BaseToolbar.Root,
3514
3663
  {
3515
3664
  "aria-label": ariaLabel,
@@ -3520,27 +3669,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
3520
3669
  }
3521
3670
  );
3522
3671
  if (!surface) return strip;
3523
- return /* @__PURE__ */ jsx51(MenuPanel, { className: "w-fit p-1", children: strip });
3672
+ return /* @__PURE__ */ jsx54(MenuPanel, { className: "w-fit p-1", children: strip });
3524
3673
  }
3525
3674
  function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
3526
- return /* @__PURE__ */ jsx51(
3675
+ return /* @__PURE__ */ jsx54(
3527
3676
  BaseToolbar.Button,
3528
3677
  {
3529
3678
  ref,
3530
3679
  disabled: disabled || !!disabledReason,
3531
3680
  focusableWhenDisabled: true,
3532
- render: /* @__PURE__ */ jsx51(IconButton, { disabled, disabledReason, ...props })
3681
+ render: /* @__PURE__ */ jsx54(IconButton, { disabled, disabledReason, ...props })
3533
3682
  }
3534
3683
  );
3535
3684
  }
3536
3685
  function ToolbarLink({ ref, href, ...props }) {
3537
- return /* @__PURE__ */ jsx51(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx51(IconButton, { href, ...props }) });
3686
+ return /* @__PURE__ */ jsx54(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx54(IconButton, { href, ...props }) });
3538
3687
  }
3539
3688
  function ToolbarInput({ size, ...props }) {
3540
- return /* @__PURE__ */ jsx51(BaseToolbar.Input, { render: /* @__PURE__ */ jsx51(TextInput, { size }), ...props });
3689
+ return /* @__PURE__ */ jsx54(BaseToolbar.Input, { render: /* @__PURE__ */ jsx54(TextInput, { size }), ...props });
3541
3690
  }
3542
3691
  function ToolbarSeparator({ className }) {
3543
- return /* @__PURE__ */ jsx51(
3692
+ return /* @__PURE__ */ jsx54(
3544
3693
  BaseToolbar.Separator,
3545
3694
  {
3546
3695
  orientation: "vertical",
@@ -3550,9 +3699,9 @@ function ToolbarSeparator({ className }) {
3550
3699
  }
3551
3700
 
3552
3701
  // src/ReactionPicker.tsx
3553
- import { jsx as jsx52 } from "react/jsx-runtime";
3702
+ import { jsx as jsx55 } from "react/jsx-runtime";
3554
3703
  function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
3555
- return /* @__PURE__ */ jsx52(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
3704
+ return /* @__PURE__ */ jsx55(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
3556
3705
  /*
3557
3706
  A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
3558
3707
  would become the toolbar's item and the button inside it would never
@@ -3562,14 +3711,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
3562
3711
  The tooltip names it for a pointer, `aria-label` for everything else,
3563
3712
  and both say the meaning rather than the glyph.
3564
3713
  */
3565
- /* @__PURE__ */ jsx52(
3714
+ /* @__PURE__ */ jsx55(
3566
3715
  ToolbarButton,
3567
3716
  {
3568
3717
  "aria-label": option.label,
3569
3718
  tooltip: option.label,
3570
3719
  onClick: () => onSelect(option.emoji),
3571
3720
  className: "size-7",
3572
- children: /* @__PURE__ */ jsx52("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
3721
+ children: /* @__PURE__ */ jsx55("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
3573
3722
  },
3574
3723
  option.emoji
3575
3724
  )
@@ -3578,23 +3727,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
3578
3727
 
3579
3728
  // src/PreviewCard.tsx
3580
3729
  import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
3581
- import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
3730
+ import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
3582
3731
  var GAP6 = 12;
3583
3732
  var VIEWPORT_PAD6 = 8;
3584
3733
  var OPEN_DELAY2 = 350;
3585
3734
  var CLOSE_DELAY = 200;
3586
3735
  function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
3587
- return /* @__PURE__ */ jsxs36(BasePreviewCard.Root, { children: [
3588
- /* @__PURE__ */ jsx53(
3736
+ return /* @__PURE__ */ jsxs39(BasePreviewCard.Root, { children: [
3737
+ /* @__PURE__ */ jsx56(
3589
3738
  BasePreviewCard.Trigger,
3590
3739
  {
3591
3740
  delay,
3592
3741
  closeDelay,
3593
- render: /* @__PURE__ */ jsx53("span", { className: cn("inline-flex", wrapperClassName) }),
3742
+ render: /* @__PURE__ */ jsx56("span", { className: cn("inline-flex", wrapperClassName) }),
3594
3743
  children
3595
3744
  }
3596
3745
  ),
3597
- /* @__PURE__ */ jsx53(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx53(
3746
+ /* @__PURE__ */ jsx56(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx56(
3598
3747
  BasePreviewCard.Positioner,
3599
3748
  {
3600
3749
  side,
@@ -3602,12 +3751,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
3602
3751
  sideOffset: GAP6,
3603
3752
  collisionPadding: VIEWPORT_PAD6,
3604
3753
  className: "z-50 data-[anchor-hidden]:hidden",
3605
- children: /* @__PURE__ */ jsx53(
3754
+ children: /* @__PURE__ */ jsx56(
3606
3755
  BasePreviewCard.Popup,
3607
3756
  {
3608
3757
  className: cn("w-[360px] p-0 outline-none", className),
3609
- render: /* @__PURE__ */ jsx53(MenuPanel, {}),
3610
- children: /* @__PURE__ */ jsx53(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
3758
+ render: /* @__PURE__ */ jsx56(MenuPanel, {}),
3759
+ children: /* @__PURE__ */ jsx56(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
3611
3760
  }
3612
3761
  )
3613
3762
  }
@@ -3616,15 +3765,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
3616
3765
  }
3617
3766
 
3618
3767
  // src/Rail.tsx
3619
- import { jsx as jsx54 } from "react/jsx-runtime";
3768
+ import { jsx as jsx57 } from "react/jsx-runtime";
3620
3769
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
3621
- return /* @__PURE__ */ jsx54("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
3770
+ return /* @__PURE__ */ jsx57("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
3622
3771
  }
3623
3772
 
3624
3773
  // src/RailItem.tsx
3625
- import { jsx as jsx55, jsxs as jsxs37 } from "react/jsx-runtime";
3774
+ import { jsx as jsx58, jsxs as jsxs40 } from "react/jsx-runtime";
3626
3775
  function RailItem({ href, icon, label, active = false, className, ...props }) {
3627
- return /* @__PURE__ */ jsxs37(
3776
+ return /* @__PURE__ */ jsxs40(
3628
3777
  "a",
3629
3778
  {
3630
3779
  href,
@@ -3632,14 +3781,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
3632
3781
  className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
3633
3782
  ...props,
3634
3783
  children: [
3635
- /* @__PURE__ */ jsx55(
3784
+ /* @__PURE__ */ jsx58(
3636
3785
  "div",
3637
3786
  {
3638
3787
  className: cn(
3639
3788
  "flex items-center justify-center rounded-lg p-2 transition-colors",
3640
3789
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
3641
3790
  ),
3642
- children: /* @__PURE__ */ jsx55(
3791
+ children: /* @__PURE__ */ jsx58(
3643
3792
  "span",
3644
3793
  {
3645
3794
  className: cn(
@@ -3651,14 +3800,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
3651
3800
  )
3652
3801
  }
3653
3802
  ),
3654
- /* @__PURE__ */ jsx55("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
3803
+ /* @__PURE__ */ jsx58("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
3655
3804
  ]
3656
3805
  }
3657
3806
  );
3658
3807
  }
3659
3808
 
3660
3809
  // src/Property.tsx
3661
- import { jsx as jsx56, jsxs as jsxs38 } from "react/jsx-runtime";
3810
+ import { jsx as jsx59, jsxs as jsxs41 } from "react/jsx-runtime";
3662
3811
  var VALUE_CLASSES = "contents";
3663
3812
  function Property({ label, layout = "row", children, className }) {
3664
3813
  if (layout === "stacked") {
@@ -3666,25 +3815,25 @@ function Property({ label, layout = "row", children, className }) {
3666
3815
  // gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
3667
3816
  // Peek's topic-details sections already sit at 12px, Ship's rail was
3668
3817
  // 6px, and unifying means the bigger, calmer one.
3669
- /* @__PURE__ */ jsxs38("dl", { className: cn("flex flex-col gap-3", className), children: [
3670
- /* @__PURE__ */ jsx56("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
3671
- /* @__PURE__ */ jsx56("dd", { className: VALUE_CLASSES, children })
3818
+ /* @__PURE__ */ jsxs41("dl", { className: cn("flex flex-col gap-3", className), children: [
3819
+ /* @__PURE__ */ jsx59("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
3820
+ /* @__PURE__ */ jsx59("dd", { className: VALUE_CLASSES, children })
3672
3821
  ] })
3673
3822
  );
3674
3823
  }
3675
- return /* @__PURE__ */ jsxs38("dl", { className: cn("flex items-center gap-2", className), children: [
3676
- /* @__PURE__ */ jsx56("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
3677
- /* @__PURE__ */ jsx56("dd", { className: VALUE_CLASSES, children })
3824
+ return /* @__PURE__ */ jsxs41("dl", { className: cn("flex items-center gap-2", className), children: [
3825
+ /* @__PURE__ */ jsx59("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
3826
+ /* @__PURE__ */ jsx59("dd", { className: VALUE_CLASSES, children })
3678
3827
  ] });
3679
3828
  }
3680
3829
 
3681
3830
  // src/Reaction.tsx
3682
3831
  import { Toggle } from "@base-ui/react/toggle";
3683
- import { jsx as jsx57, jsxs as jsxs39 } from "react/jsx-runtime";
3832
+ import { jsx as jsx60, jsxs as jsxs42 } from "react/jsx-runtime";
3684
3833
  function Reaction({ emoji, count, pressed = false, className, ...props }) {
3685
3834
  return (
3686
3835
  // @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
3687
- /* @__PURE__ */ jsxs39(
3836
+ /* @__PURE__ */ jsxs42(
3688
3837
  Toggle,
3689
3838
  {
3690
3839
  pressed,
@@ -3706,8 +3855,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
3706
3855
  ),
3707
3856
  ...props,
3708
3857
  children: [
3709
- /* @__PURE__ */ jsx57("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
3710
- /* @__PURE__ */ jsx57("span", { className: CHIP_TEXT_CLASSES, children: count })
3858
+ /* @__PURE__ */ jsx60("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
3859
+ /* @__PURE__ */ jsx60("span", { className: CHIP_TEXT_CLASSES, children: count })
3711
3860
  ]
3712
3861
  }
3713
3862
  )
@@ -3717,9 +3866,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
3717
3866
  // src/SearchInput.tsx
3718
3867
  import "react";
3719
3868
  import { Input as Input3 } from "@base-ui/react/input";
3720
- import { jsx as jsx58, jsxs as jsxs40 } from "react/jsx-runtime";
3869
+ import { jsx as jsx61, jsxs as jsxs43 } from "react/jsx-runtime";
3721
3870
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
3722
- return /* @__PURE__ */ jsxs40(
3871
+ return /* @__PURE__ */ jsxs43(
3723
3872
  "div",
3724
3873
  {
3725
3874
  className: cn(
@@ -3731,7 +3880,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
3731
3880
  className
3732
3881
  ),
3733
3882
  children: [
3734
- /* @__PURE__ */ jsx58(
3883
+ /* @__PURE__ */ jsx61(
3735
3884
  Input3,
3736
3885
  {
3737
3886
  className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
@@ -3739,42 +3888,42 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
3739
3888
  ...props
3740
3889
  }
3741
3890
  ),
3742
- shortcut && /* @__PURE__ */ jsx58(Kbd, { children: shortcut })
3891
+ shortcut && /* @__PURE__ */ jsx61(Kbd, { children: shortcut })
3743
3892
  ]
3744
3893
  }
3745
3894
  );
3746
3895
  }
3747
3896
 
3748
3897
  // src/Panel.tsx
3749
- import { jsx as jsx59, jsxs as jsxs41 } from "react/jsx-runtime";
3898
+ import { jsx as jsx62, jsxs as jsxs44 } from "react/jsx-runtime";
3750
3899
  function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
3751
- return /* @__PURE__ */ jsxs41("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
3752
- /* @__PURE__ */ jsx59(ContainerHeader, { title, chevron, actions }),
3900
+ return /* @__PURE__ */ jsxs44("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
3901
+ /* @__PURE__ */ jsx62(ContainerHeader, { title, chevron, actions }),
3753
3902
  broken ? (
3754
3903
  // The message takes the room the body had and centres itself in it.
3755
- /* @__PURE__ */ jsx59("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
3756
- ) : /* @__PURE__ */ jsx59(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
3757
- !broken && footer && /* @__PURE__ */ jsx59("div", { className: "shrink-0", children: footer })
3904
+ /* @__PURE__ */ jsx62("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
3905
+ ) : /* @__PURE__ */ jsx62(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
3906
+ !broken && footer && /* @__PURE__ */ jsx62("div", { className: "shrink-0", children: footer })
3758
3907
  ] });
3759
3908
  }
3760
3909
  function Panel(props) {
3761
- return /* @__PURE__ */ jsx59(
3910
+ return /* @__PURE__ */ jsx62(
3762
3911
  ErrorBoundary,
3763
3912
  {
3764
3913
  label: "panel",
3765
3914
  frame: (message) => (
3766
3915
  // Only the name comes back with the message: the actions and the footer may be what threw.
3767
- /* @__PURE__ */ jsx59(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
3916
+ /* @__PURE__ */ jsx62(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
3768
3917
  ),
3769
- children: /* @__PURE__ */ jsx59(Frame, { ...props })
3918
+ children: /* @__PURE__ */ jsx62(Frame, { ...props })
3770
3919
  }
3771
3920
  );
3772
3921
  }
3773
3922
 
3774
3923
  // src/ListColumn.tsx
3775
- import { jsx as jsx60, jsxs as jsxs42 } from "react/jsx-runtime";
3924
+ import { jsx as jsx63, jsxs as jsxs45 } from "react/jsx-runtime";
3776
3925
  function Column({ title, chevron = false, titleMenu, actions, above, collapsed = false, children, className, broken = false }) {
3777
- return /* @__PURE__ */ jsxs42(
3926
+ return /* @__PURE__ */ jsxs45(
3778
3927
  "div",
3779
3928
  {
3780
3929
  className: cn(
@@ -3785,35 +3934,35 @@ function Column({ title, chevron = false, titleMenu, actions, above, collapsed =
3785
3934
  ),
3786
3935
  "data-collapsed": collapsed || void 0,
3787
3936
  children: [
3788
- /* @__PURE__ */ jsx60(ContainerHeader, { title, chevron, titleMenu, actions }),
3937
+ /* @__PURE__ */ jsx63(ContainerHeader, { title, chevron, titleMenu, actions }),
3789
3938
  above,
3790
3939
  broken ? (
3791
3940
  // The message takes the room the list had and centres itself in it (Katerina, 19 September).
3792
- /* @__PURE__ */ jsx60("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
3793
- ) : /* @__PURE__ */ jsx60(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
3941
+ /* @__PURE__ */ jsx63("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
3942
+ ) : /* @__PURE__ */ jsx63(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
3794
3943
  ]
3795
3944
  }
3796
3945
  );
3797
3946
  }
3798
3947
  function ListColumn(props) {
3799
- return /* @__PURE__ */ jsx60(
3948
+ return /* @__PURE__ */ jsx63(
3800
3949
  ErrorBoundary,
3801
3950
  {
3802
3951
  label: "list panel",
3803
3952
  frame: (message) => (
3804
3953
  // Only the name comes back with the message: the actions and the row above may be what threw.
3805
- /* @__PURE__ */ jsx60(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
3954
+ /* @__PURE__ */ jsx63(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
3806
3955
  ),
3807
- children: /* @__PURE__ */ jsx60(Column, { ...props })
3956
+ children: /* @__PURE__ */ jsx63(Column, { ...props })
3808
3957
  }
3809
3958
  );
3810
3959
  }
3811
3960
 
3812
3961
  // src/Tabs.tsx
3813
3962
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
3814
- import { jsx as jsx61, jsxs as jsxs43 } from "react/jsx-runtime";
3963
+ import { Fragment as Fragment14, jsx as jsx64, jsxs as jsxs46 } from "react/jsx-runtime";
3815
3964
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
3816
- return /* @__PURE__ */ jsx61(
3965
+ return /* @__PURE__ */ jsx64(
3817
3966
  BaseTabs.Root,
3818
3967
  {
3819
3968
  value: active,
@@ -3821,14 +3970,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
3821
3970
  if (details.reason === "none") onChange(value);
3822
3971
  },
3823
3972
  className,
3824
- children: /* @__PURE__ */ jsx61(
3973
+ children: /* @__PURE__ */ jsx64(
3825
3974
  BaseTabs.List,
3826
3975
  {
3827
3976
  activateOnFocus: true,
3828
3977
  "aria-label": aria["aria-label"],
3829
3978
  "aria-labelledby": aria["aria-labelledby"],
3830
3979
  className: "flex items-center gap-2",
3831
- children: tabs.map((tab) => /* @__PURE__ */ jsxs43(
3980
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs46(
3832
3981
  BaseTabs.Tab,
3833
3982
  {
3834
3983
  value: tab.id,
@@ -3841,10 +3990,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
3841
3990
  ),
3842
3991
  children: [
3843
3992
  tab.icon,
3844
- /* @__PURE__ */ jsxs43("span", { className: "flex items-baseline", children: [
3993
+ /* @__PURE__ */ jsxs46("span", { className: "flex items-baseline", children: [
3845
3994
  tab.label,
3846
- tab.count !== void 0 ? /* @__PURE__ */ jsx61("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
3847
- ] })
3995
+ tab.count !== void 0 ? /* @__PURE__ */ jsx64("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
3996
+ ] }),
3997
+ tab.unread ? /* @__PURE__ */ jsxs46(Fragment14, { children: [
3998
+ /* @__PURE__ */ jsx64(UnreadDot, { className: "h-auto w-auto" }),
3999
+ /* @__PURE__ */ jsx64("span", { className: "sr-only", children: "new" })
4000
+ ] }) : null
3848
4001
  ]
3849
4002
  },
3850
4003
  tab.id
@@ -3859,7 +4012,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
3859
4012
  import { createContext as createContext6, useContext as useContext6, useMemo as useMemo5 } from "react";
3860
4013
  import { Toast as BaseToast } from "@base-ui/react/toast";
3861
4014
  import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
3862
- import { jsx as jsx62, jsxs as jsxs44 } from "react/jsx-runtime";
4015
+ import { jsx as jsx65, jsxs as jsxs47 } from "react/jsx-runtime";
3863
4016
  var SURFACE_STYLES = {
3864
4017
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
3865
4018
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
@@ -3895,16 +4048,16 @@ var pillClassName = (type, hasAction, className) => cn(
3895
4048
  );
3896
4049
  function LeadingIcon({ type }) {
3897
4050
  const Icon = ICONS[type];
3898
- return /* @__PURE__ */ jsx62(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
4051
+ return /* @__PURE__ */ jsx65(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
3899
4052
  }
3900
4053
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
3901
4054
  const hasAction = !!(actionLabel && onAction);
3902
- return /* @__PURE__ */ jsxs44("div", { className: pillClassName(type, hasAction, className), children: [
3903
- /* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 shrink-0", children: [
3904
- leadingIcon && /* @__PURE__ */ jsx62(LeadingIcon, { type }),
3905
- /* @__PURE__ */ jsx62("span", { className: LABEL_CLASSES, children: label })
4055
+ return /* @__PURE__ */ jsxs47("div", { className: pillClassName(type, hasAction, className), children: [
4056
+ /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
4057
+ leadingIcon && /* @__PURE__ */ jsx65(LeadingIcon, { type }),
4058
+ /* @__PURE__ */ jsx65("span", { className: LABEL_CLASSES, children: label })
3906
4059
  ] }),
3907
- hasAction && /* @__PURE__ */ jsx62(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
4060
+ hasAction && /* @__PURE__ */ jsx65(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
3908
4061
  ] });
3909
4062
  }
3910
4063
  var ToastContext = createContext6(null);
@@ -3925,9 +4078,9 @@ function ToastProvider({ children }) {
3925
4078
  }),
3926
4079
  [manager]
3927
4080
  );
3928
- return /* @__PURE__ */ jsx62(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs44(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
4081
+ return /* @__PURE__ */ jsx65(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs47(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
3929
4082
  children,
3930
- /* @__PURE__ */ jsx62(BaseToast.Portal, { children: /* @__PURE__ */ jsx62(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx62(ToastList, {}) }) })
4083
+ /* @__PURE__ */ jsx65(BaseToast.Portal, { children: /* @__PURE__ */ jsx65(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx65(ToastList, {}) }) })
3931
4084
  ] }) });
3932
4085
  }
3933
4086
  function ToastList() {
@@ -3935,25 +4088,25 @@ function ToastList() {
3935
4088
  return toasts.map((toast) => {
3936
4089
  const type = toast.type ?? "neutral";
3937
4090
  const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
3938
- return /* @__PURE__ */ jsxs44(
4091
+ return /* @__PURE__ */ jsxs47(
3939
4092
  BaseToast.Root,
3940
4093
  {
3941
4094
  toast,
3942
4095
  swipeDirection: ["left", "down"],
3943
4096
  className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
3944
4097
  children: [
3945
- /* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 shrink-0", children: [
3946
- leadingIcon && /* @__PURE__ */ jsx62(LeadingIcon, { type }),
3947
- /* @__PURE__ */ jsx62(BaseToast.Title, { render: /* @__PURE__ */ jsx62("span", {}), className: LABEL_CLASSES })
4098
+ /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
4099
+ leadingIcon && /* @__PURE__ */ jsx65(LeadingIcon, { type }),
4100
+ /* @__PURE__ */ jsx65(BaseToast.Title, { render: /* @__PURE__ */ jsx65("span", {}), className: LABEL_CLASSES })
3948
4101
  ] }),
3949
- actionLabel && /* @__PURE__ */ jsx62(
4102
+ actionLabel && /* @__PURE__ */ jsx65(
3950
4103
  BaseToast.Action,
3951
4104
  {
3952
4105
  onClick: () => {
3953
4106
  onAction?.();
3954
4107
  close(toast.id);
3955
4108
  },
3956
- render: /* @__PURE__ */ jsx62(Button, { variant: "outlined", size: "small", children: actionLabel })
4109
+ render: /* @__PURE__ */ jsx65(Button, { variant: "outlined", size: "small", children: actionLabel })
3957
4110
  }
3958
4111
  )
3959
4112
  ]
@@ -4024,6 +4177,8 @@ export {
4024
4177
  Lightbox,
4025
4178
  Link,
4026
4179
  ListColumn,
4180
+ MembersDialog,
4181
+ MembersPill,
4027
4182
  Menu,
4028
4183
  MenuItem,
4029
4184
  MenuPanel,
@@ -4051,6 +4206,7 @@ export {
4051
4206
  SectionHeader,
4052
4207
  SectionLabel,
4053
4208
  Select,
4209
+ ShowMore,
4054
4210
  Sidebar,
4055
4211
  SkeletonBar,
4056
4212
  SkeletonList,