@estiva-app/ui 0.54.0 → 0.56.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 (69) hide show
  1. package/dist/BlockHandle.d.ts +47 -0
  2. package/dist/BlockHandle.d.ts.map +1 -0
  3. package/dist/CollapsibleSection.d.ts +7 -1
  4. package/dist/CollapsibleSection.d.ts.map +1 -1
  5. package/dist/ContainerHeader.d.ts +7 -1
  6. package/dist/ContainerHeader.d.ts.map +1 -1
  7. package/dist/EditorBlockHandle.d.ts +57 -0
  8. package/dist/EditorBlockHandle.d.ts.map +1 -0
  9. package/dist/IconButton.d.ts.map +1 -1
  10. package/dist/ListColumn.d.ts +2 -0
  11. package/dist/ListColumn.d.ts.map +1 -1
  12. package/dist/Menu.d.ts.map +1 -1
  13. package/dist/NavItem.d.ts.map +1 -1
  14. package/dist/NavTree.d.ts +9 -1
  15. package/dist/NavTree.d.ts.map +1 -1
  16. package/dist/PersonTrigger.d.ts.map +1 -1
  17. package/dist/SectionHeader.d.ts +22 -3
  18. package/dist/SectionHeader.d.ts.map +1 -1
  19. package/dist/SectionLabel.d.ts.map +1 -1
  20. package/dist/editor.d.ts +1 -0
  21. package/dist/editor.d.ts.map +1 -1
  22. package/dist/editor.js +127 -11
  23. package/dist/editor.js.map +4 -4
  24. package/dist/gates/index.js +1 -1
  25. package/dist/gates/index.js.map +2 -2
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +831 -624
  29. package/dist/index.js.map +4 -4
  30. package/dist/looks.d.ts +4 -0
  31. package/dist/looks.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/registry.json +302 -23
  34. package/src/BlockHandle.mdx +58 -0
  35. package/src/BlockHandle.stories.tsx +44 -0
  36. package/src/BlockHandle.test.tsx +216 -0
  37. package/src/BlockHandle.tsx +220 -0
  38. package/src/CollapsibleSection.stories.tsx +14 -1
  39. package/src/CollapsibleSection.tsx +10 -4
  40. package/src/ContainerHeader.mdx +4 -0
  41. package/src/ContainerHeader.stories.tsx +14 -0
  42. package/src/ContainerHeader.test.tsx +8 -0
  43. package/src/ContainerHeader.tsx +34 -6
  44. package/src/EditorBlockHandle.mdx +65 -0
  45. package/src/EditorBlockHandle.stories.tsx +81 -0
  46. package/src/EditorBlockHandle.tsx +181 -0
  47. package/src/IconButton.tsx +2 -1
  48. package/src/ListColumn.tsx +4 -2
  49. package/src/Menu.tsx +5 -4
  50. package/src/NavItem.test.tsx +2 -2
  51. package/src/NavItem.tsx +21 -12
  52. package/src/NavTree.mdx +16 -1
  53. package/src/NavTree.stories.tsx +49 -2
  54. package/src/NavTree.test.tsx +7 -0
  55. package/src/NavTree.tsx +21 -4
  56. package/src/PersonTrigger.tsx +6 -5
  57. package/src/SectionHeader.mdx +6 -0
  58. package/src/SectionHeader.stories.tsx +18 -0
  59. package/src/SectionHeader.test.tsx +26 -0
  60. package/src/SectionHeader.tsx +99 -23
  61. package/src/SectionLabel.tsx +6 -3
  62. package/src/Sidebar.tsx +1 -1
  63. package/src/editor.ts +1 -0
  64. package/src/eslint/no-copied-look.test.ts +2 -2
  65. package/src/gates/app-checks.ts +1 -1
  66. package/src/index.ts +1 -0
  67. package/src/looks.ts +6 -0
  68. package/src/registry/registry.test.ts +5 -5
  69. package/stories/Choosing.mdx +2 -0
package/dist/index.js CHANGED
@@ -168,7 +168,7 @@ function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className })
168
168
  {
169
169
  "aria-label": ariaLabel,
170
170
  className: cn("flex w-60 shrink-0 flex-col", !onGround && "border-r border-border-default bg-bg-surface", className),
171
- children: /* @__PURE__ */ jsx4(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
171
+ children: /* @__PURE__ */ jsx4(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-0.5 px-2.5 py-3", children })
172
172
  }
173
173
  );
174
174
  }
@@ -276,6 +276,25 @@ import {
276
276
  // src/IconButton.tsx
277
277
  import { Button as BaseButton } from "@base-ui/react/button";
278
278
 
279
+ // src/looks.ts
280
+ var FIELD_BOX_CLASSES = "bg-bg-field border border-border-field shadow-field hover:border-border-strong group-hover/field:border-border-strong focus:border-border-focus group-hover/field:focus:border-border-focus rounded-lg";
281
+ var FIELD_TEXT_CLASSES = "text-text-primary placeholder:text-text-muted";
282
+ var FIELD_DISABLED_CLASSES = "disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled disabled:border-border-field group-hover/field:disabled:border-border-field";
283
+ var FIELD_FOCUS_RING_CLASSES = "signal:transition-shadow signal:focus:shadow-focus-ring";
284
+ var FIELD_SIZE_CLASSES = {
285
+ default: "px-3 py-2 text-input-value",
286
+ small: "h-6 min-h-6 px-2 text-caption"
287
+ };
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
+ var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
290
+ var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums";
291
+ var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
292
+ var MUTED_CONTROL_CLASSES = "text-text-secondary hover:bg-bg-hover hover:text-text-primary";
293
+ var MENU_TRIGGER_CLASSES = "cursor-pointer rounded-md transition-colors hover:bg-bg-hover data-[popup-open]:bg-bg-hover";
294
+ var SIDEBAR_ROW_CLASSES = "rounded-lg transition-colors";
295
+ var SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
296
+ var COLLAPSIBLE_PANEL_CLASSES = "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0";
297
+
279
298
  // src/formBusy.ts
280
299
  import { createContext as createContext2, useContext as useContext2 } from "react";
281
300
  var FormBusyContext = createContext2(false);
@@ -306,23 +325,6 @@ function Kbd({ children, className, tone = "default" }) {
306
325
  );
307
326
  }
308
327
 
309
- // src/looks.ts
310
- var FIELD_BOX_CLASSES = "bg-bg-field border border-border-field shadow-field hover:border-border-strong group-hover/field:border-border-strong focus:border-border-focus group-hover/field:focus:border-border-focus rounded-lg";
311
- var FIELD_TEXT_CLASSES = "text-text-primary placeholder:text-text-muted";
312
- var FIELD_DISABLED_CLASSES = "disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled disabled:border-border-field group-hover/field:disabled:border-border-field";
313
- var FIELD_FOCUS_RING_CLASSES = "signal:transition-shadow signal:focus:shadow-focus-ring";
314
- var FIELD_SIZE_CLASSES = {
315
- default: "px-3 py-2 text-input-value",
316
- small: "h-6 min-h-6 px-2 text-caption"
317
- };
318
- 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";
319
- var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
320
- var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums";
321
- var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
322
- var SIDEBAR_ROW_CLASSES = "rounded-lg transition-colors";
323
- var SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
324
- var COLLAPSIBLE_PANEL_CLASSES = "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0";
325
-
326
328
  // src/Tooltip.tsx
327
329
  import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
328
330
  var OPEN_DELAY = 300;
@@ -410,7 +412,7 @@ function IconButton({
410
412
  // stretched and carries no `self-center` — see the note there.
411
413
  "flex items-center justify-center p-1 rounded-lg transition-colors shrink-0 self-center cursor-pointer",
412
414
  !off && variant === "primary" && "bg-accent-primary hover:bg-accent-hover text-text-inverse",
413
- !off && (variant === "muted" || variant === "resolve") && "text-text-secondary hover:bg-bg-hover hover:text-text-primary",
415
+ !off && (variant === "muted" || variant === "resolve") && MUTED_CONTROL_CLASSES,
414
416
  !off && variant === "outlined" && "border border-border-default hover:bg-bg-hover text-text-secondary",
415
417
  !off && variant === "current" && "hover:bg-bg-hover",
416
418
  off && variant === "primary" && "bg-bg-disabled text-text-disabled",
@@ -948,109 +950,9 @@ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismi
948
950
  ] });
949
951
  }
950
952
 
951
- // src/Checkbox.tsx
952
- import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
953
- import { Field as BaseField } from "@base-ui/react/field";
954
- import { IconCheck } from "@tabler/icons-react";
955
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
956
- function squareClasses(checked, disabled, interactive, className) {
957
- return cn(
958
- "inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
959
- checked ? "bg-accent-primary border-accent-primary text-text-inverse" : "bg-transparent border-border-strong hover:border-text-muted",
960
- disabled && "opacity-50 pointer-events-none",
961
- interactive ? "cursor-pointer" : "pointer-events-none",
962
- className
963
- );
964
- }
965
- var tickClasses = (checked) => cn("flex", !checked && "invisible");
966
- var WORDS_CLASSES = "text-body-2 text-text-primary";
967
- var ROW_CLASSES = "flex shrink-0 items-center gap-3 h-10 px-3 rounded-lg transition-colors";
968
- function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row, leading, className, ...aria }) {
969
- const formBusy = useFormBusy();
970
- const disabled = ownDisabled || formBusy;
971
- if (!onChange) {
972
- const picture = /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx16("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx16(IconCheck, { size: 12, stroke: 3 }) }) });
973
- if (label === void 0) return picture;
974
- return /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2", children: [
975
- picture,
976
- /* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
977
- ] });
978
- }
979
- const box = /* @__PURE__ */ jsx16(
980
- BaseCheckbox.Root,
981
- {
982
- checked,
983
- disabled,
984
- "aria-label": aria["aria-label"],
985
- "aria-required": aria["aria-required"],
986
- onCheckedChange: (next) => onChange(next),
987
- onClick: (e) => e.stopPropagation(),
988
- className: (state) => squareClasses(state.checked, state.disabled, true, className),
989
- children: /* @__PURE__ */ jsx16(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx16(IconCheck, { size: 12, stroke: 3 }) })
990
- }
991
- );
992
- if (label === void 0) return box;
993
- if (row) {
994
- return /* @__PURE__ */ jsx16(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
995
- leading,
996
- /* @__PURE__ */ jsx16("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
997
- box
998
- ] }) });
999
- }
1000
- return /* @__PURE__ */ jsx16(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
1001
- box,
1002
- /* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
1003
- ] }) });
1004
- }
1005
-
1006
- // src/Chip.tsx
1007
- import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
1008
- var typeStyles = {
1009
- neutral: "bg-bg-inset text-text-primary",
1010
- brand: "bg-accent-muted text-accent-text signal:border signal:border-accent-outline",
1011
- info: "bg-info-muted text-info-default signal:border signal:border-info-outline",
1012
- warning: "bg-warning-muted text-warning-default signal:border signal:border-warning-outline signal:shadow-glow-warning",
1013
- success: "bg-success-muted text-success-default signal:border signal:border-success-outline",
1014
- error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
1015
- };
1016
- function Chip({ type = "neutral", label, leadingIcon, trailingIcon, href, onClick, className }) {
1017
- 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);
1018
- const inside = /* @__PURE__ */ jsxs11(Fragment3, { children: [
1019
- leadingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
1020
- label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
1021
- // of growing past it — Ship's project chip on an issue row
1022
- // (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
1023
- // `truncate`, because `truncate` is `overflow: hidden` on both axes and
1024
- // the label's line box (11px under Signal) is tighter than its glyphs —
1025
- // the screenshot diff caught every descender cut off. `clip` is the
1026
- // one overflow that leaves the other axis visible. A chip with no cap
1027
- // draws exactly as before.
1028
- /* @__PURE__ */ jsx17("span", { className: cn("min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap signal:tracking-wide", CHIP_TEXT_CLASSES), children: label }),
1029
- trailingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
1030
- ] });
1031
- if (href) return /* @__PURE__ */ jsx17("a", { href, onClick, className: cn("relative", classes), children: inside });
1032
- return /* @__PURE__ */ jsx17("div", { className: classes, children: inside });
1033
- }
1034
-
1035
- // src/CommandPalette.tsx
1036
- import {
1037
- createContext as createContext5,
1038
- useContext as useContext5,
1039
- useEffect as useEffect2,
1040
- useLayoutEffect as useLayoutEffect3,
1041
- useMemo as useMemo2,
1042
- useRef as useRef4,
1043
- useState as useState3
1044
- } from "react";
1045
- import { Dialog as Dialog2 } from "@base-ui/react/dialog";
1046
- import { Autocomplete } from "@base-ui/react/autocomplete";
1047
- import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
1048
-
1049
- // src/ChipInput.tsx
1050
- import { useMemo, useState as useState2 } from "react";
1051
- import { Button as BaseButton4 } from "@base-ui/react/button";
1052
- import { Combobox } from "@base-ui/react/combobox";
1053
- import { IconX as IconX4 } from "@tabler/icons-react";
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";
1054
956
 
1055
957
  // src/Menu.tsx
1056
958
  import { createContext as createContext4, useContext as useContext4 } from "react";
@@ -1060,27 +962,27 @@ import { Menu as BaseMenu } from "@base-ui/react/menu";
1060
962
  // src/Divider.tsx
1061
963
  import { createContext as createContext3, useContext as useContext3 } from "react";
1062
964
  import { Separator } from "@base-ui/react/separator";
1063
- import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
965
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
1064
966
  var DividerInPanel = createContext3(false);
1065
967
  function Divider({ orientation = "horizontal", label, tone = "default", className }) {
1066
968
  const inset = useContext3(DividerInPanel) ? "mx-0" : "mx-3";
1067
969
  if (label && orientation === "horizontal") {
1068
970
  const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
1069
- return /* @__PURE__ */ jsxs12(
971
+ return /* @__PURE__ */ jsxs10(
1070
972
  Separator,
1071
973
  {
1072
974
  orientation: "horizontal",
1073
975
  "aria-label": label,
1074
976
  className: cn("flex shrink-0 items-center gap-2", inset, className),
1075
977
  children: [
1076
- /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
1077
- /* @__PURE__ */ jsx18("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
1078
- /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
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) })
1079
981
  ]
1080
982
  }
1081
983
  );
1082
984
  }
1083
- return /* @__PURE__ */ jsx18(
985
+ return /* @__PURE__ */ jsx16(
1084
986
  Separator,
1085
987
  {
1086
988
  orientation,
@@ -1096,7 +998,7 @@ function triggerDisabled(trigger) {
1096
998
  }
1097
999
 
1098
1000
  // src/SectionLabel.tsx
1099
- import { jsx as jsx19 } from "react/jsx-runtime";
1001
+ import { jsx as jsx17 } from "react/jsx-runtime";
1100
1002
  function SectionLabel({
1101
1003
  children,
1102
1004
  tone = "primary",
@@ -1104,13 +1006,16 @@ function SectionLabel({
1104
1006
  folds = false,
1105
1007
  className
1106
1008
  }) {
1107
- return /* @__PURE__ */ jsx19(
1009
+ return /* @__PURE__ */ jsx17(
1108
1010
  "span",
1109
1011
  {
1110
1012
  className: cn(
1111
- "text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest",
1112
- // Leaf's section labels are Signal's type (Katerina, 28 September),
1113
- // but a group that folds keeps Ship's (Katerina, 2 October).
1013
+ "text-h5 leading-3",
1014
+ // Ship's type in every theme but Leaf, whose section labels are the
1015
+ // micro-label (Katerina, 28 September) unless the group folds (2
1016
+ // October). Signal dropped its micro-label on 5 October: every one of
1017
+ // Peek's section labels is Ship's type, folding or not, so Desk's
1018
+ // Screener and its Urgent and Open work read as one.
1114
1019
  !folds && "leaf:font-mono leaf:text-small leaf:uppercase leaf:tracking-widest",
1115
1020
  tone === "secondary" ? "text-text-secondary" : tone === "muted" ? "text-text-muted" : "text-text-primary",
1116
1021
  truncate && "min-w-0 truncate",
@@ -1122,14 +1027,15 @@ function SectionLabel({
1122
1027
  }
1123
1028
 
1124
1029
  // src/Menu.tsx
1125
- import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1030
+ import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
1126
1031
  var MenuContext = createContext4(null);
1127
1032
  function MenuPanel({ children, className, ...props }) {
1128
- return /* @__PURE__ */ jsx20(
1033
+ return /* @__PURE__ */ jsx18(
1129
1034
  "div",
1130
1035
  {
1131
1036
  className: cn(
1132
- "flex flex-col p-2",
1037
+ // 2px between rows, as a list column's and a sidebar's (Katerina, 5 October).
1038
+ "flex flex-col gap-0.5 p-2",
1133
1039
  FLOATING_SURFACE_CLASSES,
1134
1040
  /*
1135
1041
  * A divider in a menu runs the width of the rows it separates.
@@ -1156,7 +1062,7 @@ var VIEWPORT_PAD2 = 8;
1156
1062
  var HOVER_OPEN_DELAY = 0;
1157
1063
  var HOVER_CLOSE_DELAY = 150;
1158
1064
  function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
1159
- return /* @__PURE__ */ jsxs13(
1065
+ return /* @__PURE__ */ jsxs11(
1160
1066
  BaseMenu.Root,
1161
1067
  {
1162
1068
  open,
@@ -1164,7 +1070,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
1164
1070
  actionsRef,
1165
1071
  modal: false,
1166
1072
  children: [
1167
- /* @__PURE__ */ jsx20(
1073
+ /* @__PURE__ */ jsx18(
1168
1074
  BaseMenu.Trigger,
1169
1075
  {
1170
1076
  render: trigger,
@@ -1174,7 +1080,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
1174
1080
  closeDelay: HOVER_CLOSE_DELAY
1175
1081
  }
1176
1082
  ),
1177
- /* @__PURE__ */ jsx20(BaseMenu.Portal, { children: /* @__PURE__ */ jsx20(
1083
+ /* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
1178
1084
  BaseMenu.Positioner,
1179
1085
  {
1180
1086
  side: "bottom",
@@ -1182,13 +1088,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
1182
1088
  sideOffset: GAP2,
1183
1089
  collisionPadding: VIEWPORT_PAD2,
1184
1090
  className: "z-50 data-[anchor-hidden]:hidden",
1185
- children: /* @__PURE__ */ jsx20(
1091
+ children: /* @__PURE__ */ jsx18(
1186
1092
  BaseMenu.Popup,
1187
1093
  {
1188
1094
  "data-interactive": true,
1189
1095
  className: cn("min-w-[180px] outline-none p-0", className),
1190
- render: /* @__PURE__ */ jsx20(MenuPanel, {}),
1191
- children: /* @__PURE__ */ jsx20(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx20(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx20(DividerInPanel.Provider, { value: true, children }) }) })
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 }) }) })
1192
1098
  }
1193
1099
  )
1194
1100
  }
@@ -1204,20 +1110,20 @@ function MenuSub({ label, leading, selected, children, className }) {
1204
1110
  '[@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".'
1205
1111
  );
1206
1112
  }
1207
- return /* @__PURE__ */ jsxs13(BaseMenu.SubmenuRoot, { children: [
1208
- /* @__PURE__ */ jsx20(
1113
+ return /* @__PURE__ */ jsxs11(BaseMenu.SubmenuRoot, { children: [
1114
+ /* @__PURE__ */ jsx18(
1209
1115
  BaseMenu.SubmenuTrigger,
1210
1116
  {
1211
1117
  openOnHover: true,
1212
1118
  delay: 0,
1213
1119
  closeDelay: 150,
1214
1120
  nativeButton: true,
1215
- render: /* @__PURE__ */ jsx20("button", { type: "button" }),
1121
+ render: /* @__PURE__ */ jsx18("button", { type: "button" }),
1216
1122
  className: menuItemClassName({ size: "default", selected }),
1217
- children: /* @__PURE__ */ jsx20(MenuItemBody, { label, leading, submenu: true })
1123
+ children: /* @__PURE__ */ jsx18(MenuItemBody, { label, leading, submenu: true })
1218
1124
  }
1219
1125
  ),
1220
- /* @__PURE__ */ jsx20(BaseMenu.Portal, { children: /* @__PURE__ */ jsx20(
1126
+ /* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
1221
1127
  BaseMenu.Positioner,
1222
1128
  {
1223
1129
  side: "inline-end",
@@ -1225,7 +1131,7 @@ function MenuSub({ label, leading, selected, children, className }) {
1225
1131
  sideOffset: GAP2,
1226
1132
  collisionPadding: VIEWPORT_PAD2,
1227
1133
  className: "z-50 data-[anchor-hidden]:hidden",
1228
- children: /* @__PURE__ */ jsx20(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx20(MenuPanel, {}), children })
1134
+ children: /* @__PURE__ */ jsx18(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx18(MenuPanel, {}), children })
1229
1135
  }
1230
1136
  ) })
1231
1137
  ] });
@@ -1260,25 +1166,25 @@ function menuItemClassName({ size, selected, className }) {
1260
1166
  );
1261
1167
  }
1262
1168
  function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
1263
- const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx20(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx20(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
1264
- return /* @__PURE__ */ jsxs13(Fragment4, { children: [
1265
- leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: leading }),
1266
- children ?? /* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
1267
- /* @__PURE__ */ jsx20("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
1268
- description && /* @__PURE__ */ jsx20("span", { className: "truncate text-caption text-text-secondary", children: description })
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 })
1269
1175
  ] }),
1270
1176
  (edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
1271
1177
  // the wider of the two and never changes, so revealing the hint moves
1272
1178
  // nothing. No transition here either — the hint switches on the same
1273
1179
  // :hover / `selected` as the fill, in the same frame.
1274
- /* @__PURE__ */ jsxs13("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
1275
- edge && /* @__PURE__ */ jsx20("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
1276
- hint && /* @__PURE__ */ jsx20("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
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 })
1277
1183
  ] })
1278
1184
  ] });
1279
1185
  }
1280
1186
  function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
1281
- const body = /* @__PURE__ */ jsx20(
1187
+ const body = /* @__PURE__ */ jsx18(
1282
1188
  MenuItemBody,
1283
1189
  {
1284
1190
  label,
@@ -1296,13 +1202,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
1296
1202
  );
1297
1203
  const rowClassName = menuItemClassName({ size, selected, className });
1298
1204
  if (!useContext4(MenuContext)) {
1299
- return /* @__PURE__ */ jsx20("button", { type: "button", className: rowClassName, ...props, children: body });
1205
+ return /* @__PURE__ */ jsx18("button", { type: "button", className: rowClassName, ...props, children: body });
1300
1206
  }
1301
- return /* @__PURE__ */ jsx20(
1207
+ return /* @__PURE__ */ jsx18(
1302
1208
  BaseMenu.Item,
1303
1209
  {
1304
1210
  nativeButton: true,
1305
- render: /* @__PURE__ */ jsx20("button", { type: "button" }),
1211
+ render: /* @__PURE__ */ jsx18("button", { type: "button" }),
1306
1212
  className: rowClassName,
1307
1213
  ...props,
1308
1214
  children: body
@@ -1310,34 +1216,275 @@ function MenuItem({ label, children, size = "default", description, leading, tra
1310
1216
  );
1311
1217
  }
1312
1218
  function EnterHint({ target }) {
1313
- return /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
1314
- /* @__PURE__ */ jsx20(Kbd, { children: "\u21A9 Enter" }),
1315
- target && /* @__PURE__ */ jsx20("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider leaf:font-mono leaf:text-small leaf:tracking-wider", children: 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 })
1316
1222
  ] });
1317
1223
  }
1318
1224
  function MenuSection({ label, children, className }) {
1319
1225
  const inMenu = useContext4(MenuContext) !== null;
1320
- const heading = /* @__PURE__ */ jsx20("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx20(SectionLabel, { tone: "secondary", children: label }) });
1226
+ const heading = /* @__PURE__ */ jsx18("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx18(SectionLabel, { tone: "secondary", children: label }) });
1321
1227
  if (!inMenu) {
1322
- return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col", children: [
1228
+ return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-0.5", children: [
1323
1229
  heading,
1324
1230
  children
1325
1231
  ] });
1326
1232
  }
1327
- return /* @__PURE__ */ jsxs13(BaseMenu.Group, { className: "flex flex-col", children: [
1328
- /* @__PURE__ */ jsx20(BaseMenu.GroupLabel, { render: heading }),
1233
+ return /* @__PURE__ */ jsxs11(BaseMenu.Group, { className: "flex flex-col gap-0.5", children: [
1234
+ /* @__PURE__ */ jsx18(BaseMenu.GroupLabel, { render: heading }),
1329
1235
  children
1330
1236
  ] });
1331
1237
  }
1332
1238
  function MenuSeparator() {
1333
- return /* @__PURE__ */ jsx20(Divider, { className: "my-1" });
1239
+ return /* @__PURE__ */ jsx18(Divider, { className: "my-1" });
1334
1240
  }
1335
1241
  function MenuRow({ children, className }) {
1336
- return /* @__PURE__ */ jsx20("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
1242
+ return /* @__PURE__ */ jsx18("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
1243
+ }
1244
+
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;
1270
+ }
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));
1283
+ },
1284
+ [editing]
1285
+ );
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();
1310
+ };
1311
+ return /* @__PURE__ */ jsxs12(
1312
+ "div",
1313
+ {
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);
1337
+ },
1338
+ 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,
1345
+ {
1346
+ open,
1347
+ onOpenChange: setOpen,
1348
+ trigger: /* @__PURE__ */ jsx19(
1349
+ IconButton,
1350
+ {
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
+ ) })
1379
+ ]
1380
+ }
1381
+ );
1382
+ }
1383
+
1384
+ // src/Checkbox.tsx
1385
+ import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
1386
+ import { Field as BaseField } from "@base-ui/react/field";
1387
+ import { IconCheck } from "@tabler/icons-react";
1388
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1389
+ function squareClasses(checked, disabled, interactive, className) {
1390
+ return cn(
1391
+ "inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
1392
+ checked ? "bg-accent-primary border-accent-primary text-text-inverse" : "bg-transparent border-border-strong hover:border-text-muted",
1393
+ disabled && "opacity-50 pointer-events-none",
1394
+ interactive ? "cursor-pointer" : "pointer-events-none",
1395
+ className
1396
+ );
1337
1397
  }
1398
+ var tickClasses = (checked) => cn("flex", !checked && "invisible");
1399
+ var WORDS_CLASSES = "text-body-2 text-text-primary";
1400
+ var ROW_CLASSES = "flex shrink-0 items-center gap-3 h-10 px-3 rounded-lg transition-colors";
1401
+ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row, leading, className, ...aria }) {
1402
+ const formBusy = useFormBusy();
1403
+ const disabled = ownDisabled || formBusy;
1404
+ 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 }) }) });
1406
+ if (label === void 0) return picture;
1407
+ return /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2", children: [
1408
+ picture,
1409
+ /* @__PURE__ */ jsx20("span", { className: WORDS_CLASSES, children: label })
1410
+ ] });
1411
+ }
1412
+ const box = /* @__PURE__ */ jsx20(
1413
+ BaseCheckbox.Root,
1414
+ {
1415
+ checked,
1416
+ disabled,
1417
+ "aria-label": aria["aria-label"],
1418
+ "aria-required": aria["aria-required"],
1419
+ onCheckedChange: (next) => onChange(next),
1420
+ onClick: (e) => e.stopPropagation(),
1421
+ 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 }) })
1423
+ }
1424
+ );
1425
+ if (label === void 0) return box;
1426
+ 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: [
1428
+ leading,
1429
+ /* @__PURE__ */ jsx20("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
1430
+ box
1431
+ ] }) });
1432
+ }
1433
+ return /* @__PURE__ */ jsx20(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs13(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
1434
+ 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";
1338
1481
 
1339
1482
  // src/ChipInput.tsx
1340
- import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
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";
1341
1488
  var CHIP_BOX = (
1342
1489
  // Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
1343
1490
  // rounded-sm corners — never a forced circle — and the chip's corner
@@ -1348,10 +1495,10 @@ var CHIP_LABEL = "text-caption font-medium text-text-primary";
1348
1495
  var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
1349
1496
  var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
1350
1497
  function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
1351
- return /* @__PURE__ */ jsxs14("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
1352
- leading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: leading }),
1353
- /* @__PURE__ */ jsx21("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
1354
- onRemove && /* @__PURE__ */ jsx21(
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(
1355
1502
  BaseButton4,
1356
1503
  {
1357
1504
  type: "button",
@@ -1361,7 +1508,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
1361
1508
  },
1362
1509
  className: cn(CHIP_REMOVE, truncate && "shrink-0"),
1363
1510
  "aria-label": removeLabel ?? `Remove ${label}`,
1364
- children: /* @__PURE__ */ jsx21(IconX4, { size: 10, stroke: 1.5 })
1511
+ children: /* @__PURE__ */ jsx22(IconX4, { size: 10, stroke: 1.5 })
1365
1512
  }
1366
1513
  )
1367
1514
  ] });
@@ -1377,8 +1524,8 @@ function ChipInput({
1377
1524
  rowLeading,
1378
1525
  ...aria
1379
1526
  }) {
1380
- const [query, setQuery] = useState2("");
1381
- const [box, setBox] = useState2(null);
1527
+ const [query, setQuery] = useState3("");
1528
+ const [box, setBox] = useState3(null);
1382
1529
  const available = useMemo(() => {
1383
1530
  const chosen = new Set(value.map((o) => o.id));
1384
1531
  const excluded = new Set(excludeIds);
@@ -1414,7 +1561,7 @@ function ChipInput({
1414
1561
  setQuery("");
1415
1562
  }
1416
1563
  }
1417
- return /* @__PURE__ */ jsxs14(
1564
+ return /* @__PURE__ */ jsxs15(
1418
1565
  Combobox.Root,
1419
1566
  {
1420
1567
  multiple: true,
@@ -1431,13 +1578,13 @@ function ChipInput({
1431
1578
  filter,
1432
1579
  itemToStringLabel: (option) => option.label,
1433
1580
  children: [
1434
- /* @__PURE__ */ jsxs14(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: [
1435
- value.map((option) => /* @__PURE__ */ jsxs14(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
1436
- chipLeading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
1437
- /* @__PURE__ */ jsx21("span", { className: CHIP_LABEL, children: option.label }),
1438
- /* @__PURE__ */ jsx21(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx21(IconX4, { size: 10, stroke: 1.5 }) })
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 }) })
1439
1586
  ] }, option.id)),
1440
- /* @__PURE__ */ jsx21(
1587
+ /* @__PURE__ */ jsx22(
1441
1588
  Combobox.Input,
1442
1589
  {
1443
1590
  autoFocus,
@@ -1449,18 +1596,18 @@ function ChipInput({
1449
1596
  }
1450
1597
  )
1451
1598
  ] }),
1452
- /* @__PURE__ */ jsx21(Combobox.Portal, { children: /* @__PURE__ */ jsx21(
1599
+ /* @__PURE__ */ jsx22(Combobox.Portal, { children: /* @__PURE__ */ jsx22(
1453
1600
  Combobox.Positioner,
1454
1601
  {
1455
1602
  anchor: box,
1456
1603
  sideOffset: GAP3,
1457
1604
  collisionPadding: VIEWPORT_PAD3,
1458
1605
  className: "z-50 data-[anchor-hidden]:hidden",
1459
- children: /* @__PURE__ */ jsx21(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx21(MenuPanel, {}), children: /* @__PURE__ */ jsx21(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx21(Combobox.List, { children: (option) => /* @__PURE__ */ jsx21(
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, { children: (option) => /* @__PURE__ */ jsx22(
1460
1607
  Combobox.Item,
1461
1608
  {
1462
1609
  value: option,
1463
- render: /* @__PURE__ */ jsx21(
1610
+ render: /* @__PURE__ */ jsx22(
1464
1611
  MenuItem,
1465
1612
  {
1466
1613
  size: "tall",
@@ -1483,22 +1630,22 @@ var VIEWPORT_PAD3 = 8;
1483
1630
 
1484
1631
  // src/EmptyState.tsx
1485
1632
  import { IconMessage2 } from "@tabler/icons-react";
1486
- import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1633
+ import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1487
1634
  function EmptyState({ icon, message, scope = "page", action, className }) {
1488
1635
  if (scope === "section") {
1489
- return /* @__PURE__ */ jsx22("p", { className: cn("text-caption text-text-muted", className), children: message });
1636
+ return /* @__PURE__ */ jsx23("p", { className: cn("text-caption text-text-muted", className), children: message });
1490
1637
  }
1491
- return /* @__PURE__ */ jsxs15("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1492
- /* @__PURE__ */ jsx22("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx22(IconMessage2, { size: 16, stroke: 1.5 }) }),
1493
- /* @__PURE__ */ jsx22("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
1494
- action && /* @__PURE__ */ jsx22(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
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 })
1495
1642
  ] });
1496
1643
  }
1497
1644
 
1498
1645
  // src/Field.tsx
1499
1646
  import { cloneElement, isValidElement } from "react";
1500
1647
  import { Field as BaseField2 } from "@base-ui/react/field";
1501
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1648
+ import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1502
1649
  var LINE_STYLES = {
1503
1650
  helper: "text-caption text-text-muted",
1504
1651
  warning: "text-caption text-warning-default",
@@ -1512,27 +1659,27 @@ function Field({ label, required = false, helper, error, children }) {
1512
1659
  // `group/field`: the label, the box and the line under it are one thing under the pointer —
1513
1660
  // anywhere in it strengthens the box's border, as hovering the box does (Katerina, 28 September).
1514
1661
  // Before, the 8px between the label and the box was a gap where the border went out again.
1515
- /* @__PURE__ */ jsxs16(BaseField2.Root, { invalid: !!error, className: "group/field flex flex-col gap-2", children: [
1516
- /* @__PURE__ */ jsxs16(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
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: [
1517
1664
  label,
1518
- required && /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1665
+ required && /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1519
1666
  ] }),
1520
- /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
1667
+ /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1.5", children: [
1521
1668
  control,
1522
- error != null ? /* @__PURE__ */ jsx23(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx23(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
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
1523
1670
  ] })
1524
1671
  ] })
1525
1672
  );
1526
1673
  }
1527
1674
  function FieldLine({ tone = "helper", children, className }) {
1528
- return /* @__PURE__ */ jsx23("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1675
+ return /* @__PURE__ */ jsx24("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1529
1676
  }
1530
1677
 
1531
1678
  // src/Form.tsx
1532
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
1679
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef4 } from "react";
1533
1680
  import { Fieldset } from "@base-ui/react/fieldset";
1534
1681
  import { Form as BaseForm } from "@base-ui/react/form";
1535
- import { jsx as jsx24 } from "react/jsx-runtime";
1682
+ import { jsx as jsx25 } from "react/jsx-runtime";
1536
1683
  var FIELDS_CLASSES = "flex flex-col gap-6";
1537
1684
  var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
1538
1685
  var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
@@ -1550,12 +1697,12 @@ function firstInvalid(form) {
1550
1697
  function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fields", className, children, ...props }) {
1551
1698
  const outerBusy = useFormBusy();
1552
1699
  const busy = ownBusy || outerBusy;
1553
- const form = useRef3(null);
1554
- const busyNow = useRef3(busy);
1700
+ const form = useRef4(null);
1701
+ const busyNow = useRef4(busy);
1555
1702
  busyNow.current = busy;
1556
- const sender = useRef3(null);
1557
- const holding = useRef3(false);
1558
- const lastInside = useRef3(null);
1703
+ const sender = useRef4(null);
1704
+ const holding = useRef4(false);
1705
+ const lastInside = useRef4(null);
1559
1706
  useLayoutEffect2(() => {
1560
1707
  const element = form.current;
1561
1708
  if (!element) return;
@@ -1592,7 +1739,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fi
1592
1739
  const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
1593
1740
  if (enterSends && oneLine) form.current?.requestSubmit();
1594
1741
  };
1595
- return /* @__PURE__ */ jsx24(
1742
+ return /* @__PURE__ */ jsx25(
1596
1743
  BaseForm,
1597
1744
  {
1598
1745
  ref: form,
@@ -1615,29 +1762,29 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fi
1615
1762
  if (busyNow.current) return;
1616
1763
  void onSubmit();
1617
1764
  },
1618
- children: /* @__PURE__ */ jsx24(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx24(FormBusyContext.Provider, { value: busy, children }) })
1765
+ children: /* @__PURE__ */ jsx25(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx25(FormBusyContext.Provider, { value: busy, children }) })
1619
1766
  }
1620
1767
  );
1621
1768
  }
1622
1769
 
1623
1770
  // src/Skeleton.tsx
1624
- import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1771
+ import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
1625
1772
  function SkeletonBar({ className, style }) {
1626
- return /* @__PURE__ */ jsx25("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1773
+ return /* @__PURE__ */ jsx26("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1627
1774
  }
1628
1775
  var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
1629
1776
  function SkeletonRow({ barWidth = 130 }) {
1630
- return /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1631
- /* @__PURE__ */ jsx25(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1632
- /* @__PURE__ */ jsx25(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
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 } })
1633
1780
  ] });
1634
1781
  }
1635
1782
  function SkeletonList({ rows = 8, className }) {
1636
- return /* @__PURE__ */ jsx25("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx25(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
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)) });
1637
1784
  }
1638
1785
 
1639
1786
  // src/CommandPalette.tsx
1640
- import { Fragment as Fragment5, jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
1787
+ import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
1641
1788
  var PaletteContext = createContext5(null);
1642
1789
  function usePalette(part) {
1643
1790
  const palette = useContext5(PaletteContext);
@@ -1652,8 +1799,8 @@ function firstControl(popup) {
1652
1799
  return popup.querySelector("[data-command-palette-fields]")?.querySelector(CONTROL2) ?? null;
1653
1800
  }
1654
1801
  function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", children }) {
1655
- const popupRef = useRef4(null);
1656
- useEffect2(() => {
1802
+ const popupRef = useRef5(null);
1803
+ useEffect3(() => {
1657
1804
  if (!open) return;
1658
1805
  const frame = requestAnimationFrame(() => {
1659
1806
  const popup = popupRef.current;
@@ -1663,9 +1810,9 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
1663
1810
  return () => cancelAnimationFrame(frame);
1664
1811
  });
1665
1812
  const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
1666
- return /* @__PURE__ */ jsx26(Dialog2.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs18(Dialog2.Portal, { children: [
1667
- /* @__PURE__ */ jsx26(Dialog2.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1668
- /* @__PURE__ */ jsx26(Dialog2.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx26(
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(
1669
1816
  Dialog2.Popup,
1670
1817
  {
1671
1818
  ref: popupRef,
@@ -1675,13 +1822,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
1675
1822
  if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
1676
1823
  },
1677
1824
  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",
1678
- children: /* @__PURE__ */ jsx26(PaletteContext.Provider, { value: context, children })
1825
+ children: /* @__PURE__ */ jsx27(PaletteContext.Provider, { value: context, children })
1679
1826
  }
1680
1827
  ) })
1681
1828
  ] }) });
1682
1829
  }
1683
1830
  function LevelChip({ chip, onBack }) {
1684
- return /* @__PURE__ */ jsx26(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
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" });
1685
1832
  }
1686
1833
  function useBack(chip, popupRef) {
1687
1834
  return () => {
@@ -1692,10 +1839,10 @@ function useBack(chip, popupRef) {
1692
1839
  }
1693
1840
  function Footer({ keys }) {
1694
1841
  const { where } = usePalette("The footer");
1695
- return /* @__PURE__ */ jsxs18("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted leaf:font-mono leaf:text-small", children: [
1696
- /* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate", children: where }),
1697
- keys.map(([key, word]) => /* @__PURE__ */ jsxs18("span", { className: "flex shrink-0 items-center gap-1.5", children: [
1698
- /* @__PURE__ */ jsx26(Kbd, { children: key }),
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 }),
1699
1846
  " ",
1700
1847
  word
1701
1848
  ] }, key))
@@ -1707,12 +1854,12 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1707
1854
  const back = useBack(chip, popupRef);
1708
1855
  const items = useMemo2(() => groups.filter((g) => g.rows.length > 0).map((g) => ({ value: g.label, items: g.rows })), [groups]);
1709
1856
  const rows = items.flatMap((g) => g.items);
1710
- const [litId, setLitId] = useState3();
1857
+ const [litId, setLitId] = useState4();
1711
1858
  const lit = litId === void 0 ? void 0 : rows.find((r) => r.id === litId);
1712
- const inputRef = useRef4(null);
1713
- const reported = useRef4({});
1714
- const settled = useRef4(null);
1715
- const moved = useRef4(false);
1859
+ const inputRef = useRef5(null);
1860
+ const reported = useRef5({});
1861
+ const settled = useRef5(null);
1862
+ const moved = useRef5(false);
1716
1863
  useLayoutEffect3(() => {
1717
1864
  const before = settled.current;
1718
1865
  const now = reported.current;
@@ -1772,7 +1919,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1772
1919
  ...chip && query === "" ? [["Backspace", "back"]] : [],
1773
1920
  ["Esc", "close"]
1774
1921
  ];
1775
- return /* @__PURE__ */ jsxs18(
1922
+ return /* @__PURE__ */ jsxs19(
1776
1923
  Autocomplete.Root,
1777
1924
  {
1778
1925
  items,
@@ -1795,10 +1942,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1795
1942
  setLitId(id);
1796
1943
  },
1797
1944
  children: [
1798
- /* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1799
- /* @__PURE__ */ jsx26(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
1800
- chip && /* @__PURE__ */ jsx26(LevelChip, { chip, onBack: back }),
1801
- /* @__PURE__ */ jsx26(
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(
1802
1949
  Autocomplete.Input,
1803
1950
  {
1804
1951
  ref: inputRef,
@@ -1810,43 +1957,43 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1810
1957
  }
1811
1958
  )
1812
1959
  ] }),
1813
- /* @__PURE__ */ jsxs18(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
1814
- children != null && /* @__PURE__ */ jsx26("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
1815
- /* @__PURE__ */ jsx26(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs18(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
1816
- /* @__PURE__ */ jsx26(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx26(SectionLabel, { tone: "secondary", children: group.value }) }),
1817
- /* @__PURE__ */ jsx26(Autocomplete.Collection, { children: (row) => (
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", 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) => (
1818
1965
  /* The menu row, as the list's own option — the way Select
1819
1966
  puts it on `Select.Item`. One row, two parts. */
1820
- /* @__PURE__ */ jsx26(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx26(
1967
+ /* @__PURE__ */ jsx27(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx27(
1821
1968
  MenuItemBody,
1822
1969
  {
1823
1970
  size: "tall",
1824
1971
  label: row.label,
1825
1972
  description: row.description,
1826
- leading: /* @__PURE__ */ jsx26(RowLeading, { row }),
1973
+ leading: /* @__PURE__ */ jsx27(RowLeading, { row }),
1827
1974
  submenu: !!row.onGoIn,
1828
- hint: row.onGoIn ? /* @__PURE__ */ jsx26(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx26(EnterHint, {})
1975
+ hint: row.onGoIn ? /* @__PURE__ */ jsx27(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx27(EnterHint, {})
1829
1976
  }
1830
1977
  ) }, row.id)
1831
1978
  ) })
1832
1979
  ] }, group.value) }),
1833
- /* @__PURE__ */ jsx26(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs18(Fragment5, { children: [
1834
- /* @__PURE__ */ jsx26(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
1835
- /* @__PURE__ */ jsx26("span", { className: "text-caption text-text-muted", children: pending })
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 })
1836
1983
  ] }) }),
1837
- notes.map((note) => /* @__PURE__ */ jsx26("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx26(FieldLine, { children: note }) }, note)),
1838
- /* @__PURE__ */ jsx26(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx26(EmptyState, { scope: "section", message: empty }) })
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 }) })
1839
1986
  ] }),
1840
- /* @__PURE__ */ jsx26(Footer, { keys })
1987
+ /* @__PURE__ */ jsx27(Footer, { keys })
1841
1988
  ]
1842
1989
  }
1843
1990
  );
1844
1991
  }
1845
1992
  function RowLeading({ row }) {
1846
1993
  if (row.icon != null) {
1847
- return /* @__PURE__ */ jsx26("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
1994
+ return /* @__PURE__ */ jsx27("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
1848
1995
  }
1849
- return /* @__PURE__ */ jsx26("span", { className: "flex size-8 items-center justify-center", children: row.leading });
1996
+ return /* @__PURE__ */ jsx27("span", { className: "flex size-8 items-center justify-center", children: row.leading });
1850
1997
  }
1851
1998
  var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1852
1999
  function isTextField(el) {
@@ -1856,9 +2003,9 @@ function isTextField(el) {
1856
2003
  function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, working, error, children }) {
1857
2004
  const { modKey, popupRef } = usePalette("CommandPaletteForm");
1858
2005
  const back = useBack(chip, popupRef);
1859
- const frameRef = useRef4(null);
2006
+ const frameRef = useRef5(null);
1860
2007
  const busy = !!working;
1861
- const busyRef = useRef4(busy);
2008
+ const busyRef = useRef5(busy);
1862
2009
  busyRef.current = busy;
1863
2010
  const firstInvalid2 = () => frameRef.current?.querySelector("[data-invalid]")?.querySelector(CONTROL2) ?? null;
1864
2011
  const submit = () => {
@@ -1874,7 +2021,7 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
1874
2021
  if (isTextField(el)) return el.value === "";
1875
2022
  return ![...frame.querySelectorAll("input, textarea")].some(isTextField);
1876
2023
  };
1877
- const [backNamed, setBackNamed] = useState3(false);
2024
+ const [backNamed, setBackNamed] = useState4(false);
1878
2025
  const measure = () => setBackNamed(backWorksFrom(document.activeElement));
1879
2026
  useLayoutEffect3(measure);
1880
2027
  const onKeyDown = (e) => {
@@ -1888,65 +2035,65 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
1888
2035
  ...backNamed ? [["Backspace", "back"]] : [],
1889
2036
  ["Esc", "close"]
1890
2037
  ];
1891
- return /* @__PURE__ */ jsxs18("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
1892
- /* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1893
- icon != null && /* @__PURE__ */ jsx26("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
1894
- /* @__PURE__ */ jsx26(LevelChip, { chip, onBack: back })
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 })
1895
2042
  ] }),
1896
- /* @__PURE__ */ jsxs18(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, layout: "free", className: "flex min-h-0 flex-col", children: [
1897
- /* @__PURE__ */ jsx26(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx26("div", { className: FIELDS_CLASSES, children }) }),
1898
- /* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
1899
- /* @__PURE__ */ jsx26("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx26(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx26(FieldLine, { tone: "error", children: error }) : null }),
1900
- /* @__PURE__ */ jsx26(
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(
1901
2048
  Button,
1902
2049
  {
1903
2050
  type: "submit",
1904
2051
  variant: "primary",
1905
2052
  disabled: busy,
1906
2053
  disabledReason: busy ? void 0 : submitWaits,
1907
- leadingIcon: busy ? /* @__PURE__ */ jsx26(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
2054
+ leadingIcon: busy ? /* @__PURE__ */ jsx27(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
1908
2055
  children: working ? working.button : submitLabel
1909
2056
  }
1910
2057
  )
1911
2058
  ] })
1912
2059
  ] }),
1913
- /* @__PURE__ */ jsx26(Footer, { keys })
2060
+ /* @__PURE__ */ jsx27(Footer, { keys })
1914
2061
  ] });
1915
2062
  }
1916
2063
  var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
1917
2064
  function CommandPaletteWorking({ children, bars = 2 }) {
1918
- return /* @__PURE__ */ jsxs18("div", { role: "status", className: "flex flex-col gap-2", children: [
1919
- /* @__PURE__ */ jsxs18("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
1920
- /* @__PURE__ */ jsx26(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
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" }),
1921
2068
  children
1922
2069
  ] }),
1923
- BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx26(SkeletonBar, { className: cn("h-3", width) }, width))
2070
+ BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx27(SkeletonBar, { className: cn("h-3", width) }, width))
1924
2071
  ] });
1925
2072
  }
1926
2073
  function CommandPaletteAnswer({ children, note }) {
1927
2074
  const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
1928
- return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
1929
- paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx26("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
1930
- (part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx26("sup", { className: "ml-0.5 font-mono text-small text-accent-text", children: part.slice(1, -1) }, j) : part
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
1931
2078
  ) }, i)),
1932
- note && /* @__PURE__ */ jsx26(FieldLine, { children: note })
2079
+ note && /* @__PURE__ */ jsx27(FieldLine, { children: note })
1933
2080
  ] });
1934
2081
  }
1935
2082
  function CommandPaletteQuote({ children }) {
1936
- return /* @__PURE__ */ jsx26("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", 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 });
1937
2084
  }
1938
2085
  function CommandPaletteProposal({ source, mark, children }) {
1939
- return /* @__PURE__ */ jsxs18(Card, { fill: "surface", className: "flex flex-col gap-1 p-3", children: [
1940
- /* @__PURE__ */ jsxs18("span", { className: "flex items-center gap-2 text-caption text-text-secondary", 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: [
1941
2088
  mark,
1942
2089
  source
1943
2090
  ] }),
1944
- /* @__PURE__ */ jsx26("span", { className: "text-body-2 text-text-primary", children })
2091
+ /* @__PURE__ */ jsx27("span", { className: "text-body-2 text-text-primary", children })
1945
2092
  ] });
1946
2093
  }
1947
2094
 
1948
2095
  // src/InlineChip.tsx
1949
- import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
2096
+ import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
1950
2097
  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";
1951
2098
  var INLINE_CHIP_TONE_CLASSES = {
1952
2099
  /** A thing or a place — anything that is not a person. */
@@ -1968,19 +2115,19 @@ function inlineChipClassName(tone, className) {
1968
2115
  return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
1969
2116
  }
1970
2117
  function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
1971
- const body = /* @__PURE__ */ jsxs19(Fragment6, { children: [
1972
- icon && /* @__PURE__ */ jsx27("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
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 }),
1973
2120
  children
1974
2121
  ] });
1975
2122
  const classes = inlineChipClassName(tone, className);
1976
2123
  if (href === void 0) {
1977
- return /* @__PURE__ */ jsx27("span", { className: classes, ...props, children: body });
2124
+ return /* @__PURE__ */ jsx28("span", { className: classes, ...props, children: body });
1978
2125
  }
1979
- return /* @__PURE__ */ jsx27("a", { href, className: classes, ...props, children: body });
2126
+ return /* @__PURE__ */ jsx28("a", { href, className: classes, ...props, children: body });
1980
2127
  }
1981
2128
 
1982
2129
  // src/RichText.tsx
1983
- import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
2130
+ import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
1984
2131
  var RICH_TEXT_CLASSES = {
1985
2132
  base: "flex flex-col gap-1 break-words text-text-secondary",
1986
2133
  /* 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. */
@@ -2012,35 +2159,35 @@ function textWithLinks(text, renderText) {
2012
2159
  return parts.map((part, i) => {
2013
2160
  const written = part.match(WRITTEN_LINK);
2014
2161
  if (written) {
2015
- return /* @__PURE__ */ jsx28("span", { className: "break-words", children: /* @__PURE__ */ jsx28(Link, { href: written[2], external: true, onClick: keepToLink, children: written[1] }) }, i);
2162
+ return /* @__PURE__ */ jsx29("span", { className: "break-words", children: /* @__PURE__ */ jsx29(Link, { href: written[2], external: true, onClick: keepToLink, children: written[1] }) }, i);
2016
2163
  }
2017
2164
  const bare = i % 2 === 1 ? part.match(BARE_LINK) : null;
2018
2165
  if (bare) {
2019
2166
  return (
2020
2167
  // An address has no spaces to wrap at, so it may break anywhere.
2021
- /* @__PURE__ */ jsxs20("span", { className: "break-all", children: [
2022
- /* @__PURE__ */ jsx28(Link, { href: bare[1], external: true, onClick: keepToLink, children: bare[1] }),
2168
+ /* @__PURE__ */ jsxs21("span", { className: "break-all", children: [
2169
+ /* @__PURE__ */ jsx29(Link, { href: bare[1], external: true, onClick: keepToLink, children: bare[1] }),
2023
2170
  bare[2]
2024
2171
  ] }, i)
2025
2172
  );
2026
2173
  }
2027
- return part ? /* @__PURE__ */ jsx28("span", { children: renderText(part) }, i) : null;
2174
+ return part ? /* @__PURE__ */ jsx29("span", { children: renderText(part) }, i) : null;
2028
2175
  });
2029
2176
  }
2030
2177
  function Runs({ runs, draw }) {
2031
- return /* @__PURE__ */ jsx28(Fragment7, { children: (runs ?? []).map((run, i) => {
2032
- if (run.reference) return /* @__PURE__ */ jsx28("span", { children: draw.renderReference(run.reference, run) }, i);
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);
2033
2180
  if (run.marks.includes("code")) {
2034
- return /* @__PURE__ */ jsx28("code", { children: run.text }, i);
2181
+ return /* @__PURE__ */ jsx29("code", { children: run.text }, i);
2035
2182
  }
2036
- let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs20("span", { children: [
2037
- j > 0 && /* @__PURE__ */ jsx28("br", {}),
2183
+ let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs21("span", { children: [
2184
+ j > 0 && /* @__PURE__ */ jsx29("br", {}),
2038
2185
  textWithLinks(line, draw.renderText)
2039
2186
  ] }, j));
2040
- if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx28("u", { children: node });
2041
- if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx28("em", { children: node });
2042
- if (run.marks.includes("bold")) node = /* @__PURE__ */ jsx28("strong", { children: node });
2043
- return /* @__PURE__ */ jsx28("span", { children: node }, i);
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);
2044
2191
  }) });
2045
2192
  }
2046
2193
  var named = (block) => block.typeName ?? block.type;
@@ -2051,15 +2198,15 @@ function Table({ block, draw }) {
2051
2198
  const header = named(cell) === "tableHeader";
2052
2199
  const Cell = header ? "th" : "td";
2053
2200
  const { colspan, rowspan } = cell.attrs ?? {};
2054
- return /* @__PURE__ */ jsxs20(
2201
+ return /* @__PURE__ */ jsxs21(
2055
2202
  Cell,
2056
2203
  {
2057
2204
  "data-block-id": cell.id,
2058
2205
  colSpan: colspan && colspan > 1 ? colspan : void 0,
2059
2206
  rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
2060
2207
  children: [
2061
- (cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx28(Runs, { runs: child.inline, draw }, j)),
2062
- /* @__PURE__ */ jsx28(Runs, { runs: cell.inline, draw })
2208
+ (cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx29(Runs, { runs: child.inline, draw }, j)),
2209
+ /* @__PURE__ */ jsx29(Runs, { runs: cell.inline, draw })
2063
2210
  ]
2064
2211
  },
2065
2212
  cell.id ?? i
@@ -2067,43 +2214,43 @@ function Table({ block, draw }) {
2067
2214
  });
2068
2215
  const first = rows[0].children ?? [];
2069
2216
  const headerRow = first.length > 0 && first.every((cell) => named(cell) === "tableHeader");
2070
- return /* @__PURE__ */ jsxs20("table", { "data-block-id": block.id, children: [
2071
- headerRow && /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsx28("tr", { "data-block-id": rows[0].id, children: cells(rows[0]) }) }),
2072
- /* @__PURE__ */ jsx28("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx28("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
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)) })
2073
2220
  ] });
2074
2221
  }
2075
2222
  function Block({ block, draw }) {
2076
2223
  const own = draw.renderBlock?.(block);
2077
2224
  if (own !== void 0) return own;
2078
- const runs = /* @__PURE__ */ jsx28(Runs, { runs: block.inline, draw });
2225
+ const runs = /* @__PURE__ */ jsx29(Runs, { runs: block.inline, draw });
2079
2226
  switch (block.type) {
2080
2227
  case "heading": {
2081
- if (block.level === 1) return /* @__PURE__ */ jsx28("h1", { "data-block-id": block.id, children: runs });
2082
- if (block.level === 3) return /* @__PURE__ */ jsx28("h3", { "data-block-id": block.id, children: runs });
2083
- return /* @__PURE__ */ jsx28("h2", { "data-block-id": block.id, children: runs });
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 });
2084
2231
  }
2085
2232
  case "paragraph":
2086
- return /* @__PURE__ */ jsx28("p", { "data-block-id": block.id, children: runs });
2233
+ return /* @__PURE__ */ jsx29("p", { "data-block-id": block.id, children: runs });
2087
2234
  case "bulletList":
2088
2235
  case "orderedList": {
2089
- const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx28("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx28(Runs, { runs: item.inline, draw }) }, item.id ?? i));
2090
- return block.type === "bulletList" ? /* @__PURE__ */ jsx28("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx28("ol", { "data-block-id": block.id, start: block.start, children: items });
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 });
2091
2238
  }
2092
2239
  case "blockquote":
2093
- return /* @__PURE__ */ jsx28("blockquote", { "data-block-id": block.id, children: runs });
2240
+ return /* @__PURE__ */ jsx29("blockquote", { "data-block-id": block.id, children: runs });
2094
2241
  case "codeBlock":
2095
- return /* @__PURE__ */ jsx28("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx28("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
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("") }) });
2096
2243
  case "horizontalRule":
2097
- return /* @__PURE__ */ jsx28("hr", { "data-block-id": block.id });
2244
+ return /* @__PURE__ */ jsx29("hr", { "data-block-id": block.id });
2098
2245
  case "table": {
2099
- const table = /* @__PURE__ */ jsx28(Table, { block, draw });
2246
+ const table = /* @__PURE__ */ jsx29(Table, { block, draw });
2100
2247
  if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
2101
2248
  break;
2102
2249
  }
2103
2250
  }
2104
- return /* @__PURE__ */ jsxs20("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
2251
+ return /* @__PURE__ */ jsxs21("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
2105
2252
  runs,
2106
- (block.children ?? []).map((child, i) => /* @__PURE__ */ jsx28(Block, { block: child, draw }, child.id ?? i))
2253
+ (block.children ?? []).map((child, i) => /* @__PURE__ */ jsx29(Block, { block: child, draw }, child.id ?? i))
2107
2254
  ] });
2108
2255
  }
2109
2256
  function RichText({
@@ -2115,22 +2262,22 @@ function RichText({
2115
2262
  }) {
2116
2263
  if (blocks.length === 0) return null;
2117
2264
  const draw = { renderText, renderReference, renderBlock };
2118
- return /* @__PURE__ */ jsx28("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx28(Block, { block, draw }, block.id ?? i)) });
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)) });
2119
2266
  }
2120
2267
 
2121
2268
  // src/IdentityMenu.tsx
2122
- import { useCallback, useRef as useRef5 } from "react";
2269
+ import { useCallback as useCallback2, useRef as useRef6 } from "react";
2123
2270
 
2124
2271
  // src/Person.tsx
2125
- import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
2272
+ import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
2126
2273
  function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
2127
2274
  return (
2128
2275
  // gap-2: the face-to-name distance is one rule (8px) wherever a person
2129
2276
  // appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
2130
2277
  // row agree by construction.
2131
- /* @__PURE__ */ jsxs21("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
2132
- /* @__PURE__ */ jsx29(Avatar, { name, src: picture, size }),
2133
- /* @__PURE__ */ jsx29("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
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 })
2134
2281
  ] })
2135
2282
  );
2136
2283
  }
@@ -2138,10 +2285,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
2138
2285
  // src/PersonTrigger.tsx
2139
2286
  import { Button as BaseButton5 } from "@base-ui/react/button";
2140
2287
  import { IconChevronDown } from "@tabler/icons-react";
2141
- import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
2288
+ import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
2142
2289
  function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
2143
2290
  if (compact) {
2144
- return /* @__PURE__ */ jsx30(
2291
+ return /* @__PURE__ */ jsx31(
2145
2292
  BaseButton5,
2146
2293
  {
2147
2294
  type: "button",
@@ -2150,32 +2297,32 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2150
2297
  "aria-label": props["aria-label"] ?? name ?? fallback,
2151
2298
  className: cn("cursor-pointer rounded-full", className),
2152
2299
  ...props,
2153
- children: /* @__PURE__ */ jsx30(Avatar, { name, src: picture, size: size ?? 36 })
2300
+ children: /* @__PURE__ */ jsx31(Avatar, { name, src: picture, size: size ?? 36 })
2154
2301
  }
2155
2302
  );
2156
2303
  }
2157
2304
  return (
2158
2305
  // @estiva-escape(no-copied-look): N5 (Katerina, 24 September: record only): a row that fills on hover, as NavItem also does
2159
- /* @__PURE__ */ jsxs22(
2306
+ /* @__PURE__ */ jsxs23(
2160
2307
  BaseButton5,
2161
2308
  {
2162
2309
  type: "button",
2163
2310
  "aria-haspopup": "menu",
2164
2311
  "aria-expanded": open,
2165
2312
  className: cn(
2166
- "flex h-8 min-h-8 cursor-pointer items-center gap-1.5 rounded-md pl-1.5 pr-1.5 text-body-2 text-text-primary transition-colors hover:bg-bg-hover",
2313
+ "flex h-8 min-h-8 items-center gap-1.5 pl-1.5 pr-1.5 text-body-2 text-text-primary",
2314
+ MENU_TRIGGER_CLASSES,
2167
2315
  open && "bg-bg-hover",
2168
2316
  // Under a `Menu` the open state is Base UI's, not a prop: the trigger
2169
- // carries `data-popup-open` while its menu is up, and sets its own
2170
- // `aria-expanded`. Both spellings hold the fill, so this works whether
2171
- // the caller drives it or the menu does.
2172
- "data-[popup-open]:bg-bg-hover",
2317
+ // carries `data-popup-open` while its menu is up (MENU_TRIGGER_CLASSES
2318
+ // holds the fill for it), and sets its own `aria-expanded`; `open`
2319
+ // holds it for a caller that drives it.
2173
2320
  className
2174
2321
  ),
2175
2322
  ...props,
2176
2323
  children: [
2177
- /* @__PURE__ */ jsx30(Person, { name, picture, fallback, size: size ?? 22 }),
2178
- /* @__PURE__ */ jsx30(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
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" })
2179
2326
  ]
2180
2327
  }
2181
2328
  )
@@ -2183,10 +2330,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2183
2330
  }
2184
2331
 
2185
2332
  // src/IdentityMenu.tsx
2186
- import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
2333
+ import { Fragment as Fragment8, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
2187
2334
  function IdentityPanel({ className, onClose = () => {
2188
2335
  }, ...rest }) {
2189
- return /* @__PURE__ */ jsx31(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx31(IdentityRows, { ...rest, onClose }) });
2336
+ return /* @__PURE__ */ jsx32(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx32(IdentityRows, { ...rest, onClose }) });
2190
2337
  }
2191
2338
  function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
2192
2339
  const act = (action) => () => {
@@ -2194,53 +2341,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
2194
2341
  action();
2195
2342
  };
2196
2343
  const appRows = typeof children === "function" ? children(onClose) : children;
2197
- return /* @__PURE__ */ jsxs23(Fragment8, { children: [
2198
- /* @__PURE__ */ jsxs23(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
2199
- /* @__PURE__ */ jsx31(MenuRow, { children: /* @__PURE__ */ jsx31("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx31(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
2200
- /* @__PURE__ */ jsx31(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." }),
2201
- me.email && /* @__PURE__ */ jsxs23(Note, { 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: [
2202
2349
  me.email,
2203
2350
  " \xB7 known to Estiva, never published to the relay"
2204
2351
  ] })
2205
2352
  ] }),
2206
- relayUrl && /* @__PURE__ */ jsxs23(Fragment8, { children: [
2207
- /* @__PURE__ */ jsx31(Divider, { className: "mx-0 my-2" }),
2208
- /* @__PURE__ */ jsxs23(MenuSection, { label: "Workspace", children: [
2209
- /* @__PURE__ */ jsx31(MenuRow, { children: /* @__PURE__ */ jsx31("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
2210
- /* @__PURE__ */ jsx31(Note, { children: "Everyone on this relay shares this workspace, in every app." })
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." })
2211
2358
  ] })
2212
2359
  ] }),
2213
- appRows && /* @__PURE__ */ jsxs23(Fragment8, { children: [
2214
- /* @__PURE__ */ jsx31(Divider, { className: "mx-0 my-2" }),
2360
+ appRows && /* @__PURE__ */ jsxs24(Fragment8, { children: [
2361
+ /* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }),
2215
2362
  appRows
2216
2363
  ] }),
2217
- signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx31(Divider, { className: "mx-0 my-2" }) : null,
2218
- signedIn && idBase && /* @__PURE__ */ jsx31(
2364
+ signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }) : null,
2365
+ signedIn && idBase && /* @__PURE__ */ jsx32(
2219
2366
  MenuItem,
2220
2367
  {
2221
2368
  label: "Edit your profile in Estiva ID",
2222
2369
  onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
2223
2370
  }
2224
2371
  ),
2225
- onCopyKey && /* @__PURE__ */ jsx31(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2226
- idBase && onSignOut && /* @__PURE__ */ jsx31(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2372
+ onCopyKey && /* @__PURE__ */ jsx32(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2373
+ idBase && onSignOut && /* @__PURE__ */ jsx32(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2227
2374
  ] });
2228
2375
  }
2229
2376
  function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
2230
- const actions = useRef5(null);
2231
- const close = useCallback(() => actions.current?.close(), []);
2377
+ const actions = useRef6(null);
2378
+ const close = useCallback2(() => actions.current?.close(), []);
2232
2379
  return (
2233
2380
  /* The wrapper carries the caller's `className` and nothing else. It used
2234
2381
  to be `relative`, because the panel was positioned against it; the panel
2235
2382
  hangs from the trigger and portals now, so a positioning context here
2236
2383
  would only be a lie about what this box does. */
2237
- /* @__PURE__ */ jsx31("div", { className, children: /* @__PURE__ */ jsx31(
2384
+ /* @__PURE__ */ jsx32("div", { className, children: /* @__PURE__ */ jsx32(
2238
2385
  Menu,
2239
2386
  {
2240
2387
  align: "right",
2241
2388
  actionsRef: actions,
2242
2389
  className: "w-72",
2243
- trigger: /* @__PURE__ */ jsx31(
2390
+ trigger: /* @__PURE__ */ jsx32(
2244
2391
  PersonTrigger,
2245
2392
  {
2246
2393
  name: me.name,
@@ -2251,7 +2398,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2251
2398
  "aria-label": compact ? "Account menu" : void 0
2252
2399
  }
2253
2400
  ),
2254
- children: /* @__PURE__ */ jsx31(
2401
+ children: /* @__PURE__ */ jsx32(
2255
2402
  IdentityRows,
2256
2403
  {
2257
2404
  me,
@@ -2269,14 +2416,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2269
2416
  );
2270
2417
  }
2271
2418
  function Note({ children }) {
2272
- return /* @__PURE__ */ jsx31("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2419
+ return /* @__PURE__ */ jsx32("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2273
2420
  }
2274
2421
 
2275
2422
  // src/FilePicker.tsx
2276
2423
  import { forwardRef } from "react";
2277
- import { jsx as jsx32 } from "react/jsx-runtime";
2424
+ import { jsx as jsx33 } from "react/jsx-runtime";
2278
2425
  var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
2279
- return /* @__PURE__ */ jsx32(
2426
+ return /* @__PURE__ */ jsx33(
2280
2427
  "input",
2281
2428
  {
2282
2429
  ref,
@@ -2297,7 +2444,7 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
2297
2444
  // src/Select.tsx
2298
2445
  import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
2299
2446
  import { Select as BaseSelect } from "@base-ui/react/select";
2300
- import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
2447
+ import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
2301
2448
  var GAP4 = 4;
2302
2449
  var VIEWPORT_PAD4 = 8;
2303
2450
  function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
@@ -2305,7 +2452,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2305
2452
  const held = Boolean(disabledReason);
2306
2453
  const trigger = (
2307
2454
  // @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
2308
- /* @__PURE__ */ jsxs24(
2455
+ /* @__PURE__ */ jsxs25(
2309
2456
  BaseSelect.Trigger,
2310
2457
  {
2311
2458
  "aria-label": ariaLabel,
@@ -2338,21 +2485,21 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2338
2485
  className
2339
2486
  ),
2340
2487
  children: [
2341
- /* @__PURE__ */ jsxs24("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
2342
- selected?.leading && /* @__PURE__ */ jsx33("span", { className: "flex shrink-0 items-center", children: selected.leading }),
2343
- /* @__PURE__ */ jsx33(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
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 })
2344
2491
  ] }),
2345
- /* @__PURE__ */ jsx33(
2492
+ /* @__PURE__ */ jsx34(
2346
2493
  BaseSelect.Icon,
2347
2494
  {
2348
- render: /* @__PURE__ */ jsx33(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2495
+ render: /* @__PURE__ */ jsx34(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2349
2496
  }
2350
2497
  )
2351
2498
  ]
2352
2499
  }
2353
2500
  )
2354
2501
  );
2355
- return /* @__PURE__ */ jsxs24(
2502
+ return /* @__PURE__ */ jsxs25(
2356
2503
  BaseSelect.Root,
2357
2504
  {
2358
2505
  value,
@@ -2364,8 +2511,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2364
2511
  disabled: disabled && !held,
2365
2512
  modal: false,
2366
2513
  children: [
2367
- held ? /* @__PURE__ */ jsx33(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2368
- /* @__PURE__ */ jsx33(BaseSelect.Portal, { children: /* @__PURE__ */ jsx33(
2514
+ held ? /* @__PURE__ */ jsx34(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2515
+ /* @__PURE__ */ jsx34(BaseSelect.Portal, { children: /* @__PURE__ */ jsx34(
2369
2516
  BaseSelect.Positioner,
2370
2517
  {
2371
2518
  side: "bottom",
@@ -2374,25 +2521,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2374
2521
  collisionPadding: VIEWPORT_PAD4,
2375
2522
  alignItemWithTrigger: false,
2376
2523
  className: "z-50 data-[anchor-hidden]:hidden",
2377
- children: /* @__PURE__ */ jsx33(
2524
+ children: /* @__PURE__ */ jsx34(
2378
2525
  BaseSelect.Popup,
2379
2526
  {
2380
- render: /* @__PURE__ */ jsx33(MenuPanel, {}),
2527
+ render: /* @__PURE__ */ jsx34(MenuPanel, {}),
2381
2528
  className: "min-w-[var(--anchor-width)] p-0",
2382
- children: /* @__PURE__ */ jsx33(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs24(
2529
+ children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs25(
2383
2530
  BaseSelect.Item,
2384
2531
  {
2385
2532
  value: option.value,
2386
2533
  className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
2387
2534
  children: [
2388
- /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-2", children: [
2389
- option.leading && /* @__PURE__ */ jsx33("span", { className: "flex shrink-0 items-center", children: option.leading }),
2390
- /* @__PURE__ */ jsx33(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
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 })
2391
2538
  ] }),
2392
- /* @__PURE__ */ jsx33(
2539
+ /* @__PURE__ */ jsx34(
2393
2540
  BaseSelect.ItemIndicator,
2394
2541
  {
2395
- render: /* @__PURE__ */ jsx33(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2542
+ render: /* @__PURE__ */ jsx34(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2396
2543
  }
2397
2544
  )
2398
2545
  ]
@@ -2411,9 +2558,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2411
2558
  // src/TextInput.tsx
2412
2559
  import { forwardRef as forwardRef2 } from "react";
2413
2560
  import { Input } from "@base-ui/react/input";
2414
- import { jsx as jsx34 } from "react/jsx-runtime";
2561
+ import { jsx as jsx35 } from "react/jsx-runtime";
2415
2562
  var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
2416
- return /* @__PURE__ */ jsx34(
2563
+ return /* @__PURE__ */ jsx35(
2417
2564
  Input,
2418
2565
  {
2419
2566
  ref,
@@ -2439,13 +2586,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
2439
2586
  // src/Textarea.tsx
2440
2587
  import { forwardRef as forwardRef3 } from "react";
2441
2588
  import { Field as BaseField3 } from "@base-ui/react/field";
2442
- import { jsx as jsx35 } from "react/jsx-runtime";
2589
+ import { jsx as jsx36 } from "react/jsx-runtime";
2443
2590
  var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2444
- return /* @__PURE__ */ jsx35(
2591
+ return /* @__PURE__ */ jsx36(
2445
2592
  BaseField3.Control,
2446
2593
  {
2447
2594
  ref,
2448
- render: /* @__PURE__ */ jsx35("textarea", {}),
2595
+ render: /* @__PURE__ */ jsx36("textarea", {}),
2449
2596
  className: cn(
2450
2597
  // The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
2451
2598
  // "aren't there hover states in text input and text area?"). Focus comes after hover in
@@ -2464,43 +2611,57 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2464
2611
  });
2465
2612
 
2466
2613
  // src/ConfirmDialog.tsx
2467
- import { useState as useState4 } from "react";
2614
+ import { useState as useState5 } from "react";
2468
2615
 
2469
2616
  // src/DialogShell.tsx
2470
- import { useRef as useRef6 } from "react";
2617
+ import { useRef as useRef7 } from "react";
2471
2618
  import { Dialog as Dialog3 } from "@base-ui/react/dialog";
2472
2619
  import { AlertDialog } from "@base-ui/react/alert-dialog";
2473
2620
  import { IconX as IconX5 } from "@tabler/icons-react";
2474
2621
 
2475
2622
  // src/ContainerHeader.tsx
2476
2623
  import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
2477
- import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
2478
- function ContainerHeader({ title, chevron = false, actions, className }) {
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 }) {
2479
2627
  const text = typeof title === "string";
2480
- return /* @__PURE__ */ jsxs25("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4 pl-5", className), children: [
2481
- /* @__PURE__ */ jsx36("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs25("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
2482
- text ? /* @__PURE__ */ jsx36("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx36("div", { className: "min-w-0 flex-1", children: title }),
2483
- chevron && /* @__PURE__ */ jsx36(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2484
- ] }) }),
2485
- actions && /* @__PURE__ */ jsx36("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx36("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
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" })
2486
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
+ );
2487
2648
  }
2488
2649
 
2489
2650
  // src/DialogShell.tsx
2490
- import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
2651
+ import { jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
2491
2652
  function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
2492
2653
  const Parts = alert ? AlertDialog : Dialog3;
2493
- const popupRef = useRef6(null);
2494
- return /* @__PURE__ */ jsx37(
2654
+ const popupRef = useRef7(null);
2655
+ return /* @__PURE__ */ jsx38(
2495
2656
  Parts.Root,
2496
2657
  {
2497
2658
  open: true,
2498
2659
  onOpenChange: (open) => {
2499
2660
  if (!open) onClose();
2500
2661
  },
2501
- children: /* @__PURE__ */ jsxs26(Parts.Portal, { children: [
2502
- /* @__PURE__ */ jsx37(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
2503
- /* @__PURE__ */ jsx37("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs26(
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(
2504
2665
  Parts.Popup,
2505
2666
  {
2506
2667
  ref: popupRef,
@@ -2509,10 +2670,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
2509
2670
  className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
2510
2671
  style: { width },
2511
2672
  children: [
2512
- /* @__PURE__ */ jsx37(
2673
+ /* @__PURE__ */ jsx38(
2513
2674
  ContainerHeader,
2514
2675
  {
2515
- title: headerContent ?? /* @__PURE__ */ jsx37(Parts.Title, { className: "block truncate text-h4 text-text-primary", render: /* @__PURE__ */ jsx37("span", {}), children: title }),
2676
+ title: headerContent ?? /* @__PURE__ */ jsx38(Parts.Title, { className: "block truncate text-h4 text-text-primary", render: /* @__PURE__ */ jsx38("span", {}), children: title }),
2516
2677
  actions: (
2517
2678
  /*
2518
2679
  The ✕ IS the `Close` part now, rather than a button that calls
@@ -2526,10 +2687,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
2526
2687
  so the ✕, Escape and the outside press are one path with one
2527
2688
  reason attached, instead of one of the three going around.
2528
2689
  */
2529
- /* @__PURE__ */ jsx37(
2690
+ /* @__PURE__ */ jsx38(
2530
2691
  Parts.Close,
2531
2692
  {
2532
- render: /* @__PURE__ */ jsx37(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx37(IconX5, { size: 16, stroke: 1.5 }) })
2693
+ render: /* @__PURE__ */ jsx38(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx38(IconX5, { size: 16, stroke: 1.5 }) })
2533
2694
  }
2534
2695
  )
2535
2696
  )
@@ -2537,9 +2698,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
2537
2698
  ),
2538
2699
  bodyMaxHeight ? (
2539
2700
  // The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
2540
- /* @__PURE__ */ jsx37("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx37(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
2541
- ) : /* @__PURE__ */ jsx37("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
2542
- footer != null && /* @__PURE__ */ jsx37("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
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 })
2543
2704
  ]
2544
2705
  }
2545
2706
  ) })
@@ -2549,9 +2710,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
2549
2710
  }
2550
2711
 
2551
2712
  // src/ConfirmDialog.tsx
2552
- import { Fragment as Fragment9, jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
2713
+ import { Fragment as Fragment9, jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
2553
2714
  function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
2554
- const [busy, setBusy] = useState4(false);
2715
+ const [busy, setBusy] = useState5(false);
2555
2716
  const confirm = async () => {
2556
2717
  setBusy(true);
2557
2718
  try {
@@ -2561,32 +2722,32 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
2561
2722
  setBusy(false);
2562
2723
  }
2563
2724
  };
2564
- return /* @__PURE__ */ jsx38(
2725
+ return /* @__PURE__ */ jsx39(
2565
2726
  DialogShell,
2566
2727
  {
2567
2728
  alert: true,
2568
2729
  title,
2569
2730
  onClose,
2570
- footer: /* @__PURE__ */ jsxs27(Fragment9, { children: [
2571
- /* @__PURE__ */ jsx38(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2572
- /* @__PURE__ */ jsx38(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
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 })
2573
2734
  ] }),
2574
- children: /* @__PURE__ */ jsx38("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2735
+ children: /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2575
2736
  }
2576
2737
  );
2577
2738
  }
2578
2739
 
2579
2740
  // src/EditableText.tsx
2580
- import { useEffect as useEffect3, useRef as useRef7, useState as useState5 } from "react";
2741
+ import { useEffect as useEffect4, useRef as useRef8, useState as useState6 } from "react";
2581
2742
  import { Field as BaseField4 } from "@base-ui/react/field";
2582
2743
  import { Input as Input2 } from "@base-ui/react/input";
2583
- import { jsx as jsx39 } from "react/jsx-runtime";
2744
+ import { jsx as jsx40 } from "react/jsx-runtime";
2584
2745
  function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
2585
- const [editing, setEditing] = useState5(false);
2586
- const [draft, setDraft] = useState5(value);
2587
- const [busy, setBusy] = useState5(false);
2588
- const fieldRef = useRef7(null);
2589
- useEffect3(() => {
2746
+ const [editing, setEditing] = useState6(false);
2747
+ const [draft, setDraft] = useState6(value);
2748
+ const [busy, setBusy] = useState6(false);
2749
+ const fieldRef = useRef8(null);
2750
+ useEffect4(() => {
2590
2751
  if (editing) {
2591
2752
  fieldRef.current?.focus();
2592
2753
  fieldRef.current?.select();
@@ -2638,7 +2799,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2638
2799
  written and never read. Read-only, this is a line of text: whatever
2639
2800
  names the region around it (a `Field`, a `Property`) names this too.
2640
2801
  */
2641
- /* @__PURE__ */ jsx39(
2802
+ /* @__PURE__ */ jsx40(
2642
2803
  "div",
2643
2804
  {
2644
2805
  className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
@@ -2648,11 +2809,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2648
2809
  );
2649
2810
  }
2650
2811
  if (editing) {
2651
- return multiline ? /* @__PURE__ */ jsx39(
2812
+ return multiline ? /* @__PURE__ */ jsx40(
2652
2813
  BaseField4.Control,
2653
2814
  {
2654
2815
  ref: fieldRef,
2655
- render: /* @__PURE__ */ jsx39("textarea", { rows: 4 }),
2816
+ render: /* @__PURE__ */ jsx40("textarea", { rows: 4 }),
2656
2817
  "aria-label": label,
2657
2818
  value: draft,
2658
2819
  disabled: busy,
@@ -2661,7 +2822,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2661
2822
  onBlur: () => void commit(),
2662
2823
  className: fieldClass
2663
2824
  }
2664
- ) : /* @__PURE__ */ jsx39(
2825
+ ) : /* @__PURE__ */ jsx40(
2665
2826
  Input2,
2666
2827
  {
2667
2828
  ref: fieldRef,
@@ -2675,7 +2836,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2675
2836
  }
2676
2837
  );
2677
2838
  }
2678
- return /* @__PURE__ */ jsx39(
2839
+ return /* @__PURE__ */ jsx40(
2679
2840
  "button",
2680
2841
  {
2681
2842
  type: "button",
@@ -2695,7 +2856,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2695
2856
  // src/ErrorBoundary.tsx
2696
2857
  import { Component } from "react";
2697
2858
  import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
2698
- import { jsx as jsx40 } from "react/jsx-runtime";
2859
+ import { jsx as jsx41 } from "react/jsx-runtime";
2699
2860
  var ErrorBoundary = class extends Component {
2700
2861
  state = { hasError: false };
2701
2862
  static getDerivedStateFromError() {
@@ -2706,22 +2867,22 @@ var ErrorBoundary = class extends Component {
2706
2867
  }
2707
2868
  render() {
2708
2869
  if (!this.state.hasError) return this.props.children;
2709
- const message = /* @__PURE__ */ jsx40(
2870
+ const message = /* @__PURE__ */ jsx41(
2710
2871
  EmptyState,
2711
2872
  {
2712
- icon: /* @__PURE__ */ jsx40(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
2873
+ icon: /* @__PURE__ */ jsx41(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
2713
2874
  message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
2714
2875
  action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
2715
2876
  }
2716
2877
  );
2717
2878
  if (this.props.frame) return this.props.frame(message);
2718
- return this.props.fallbackClassName ? /* @__PURE__ */ jsx40("div", { className: this.props.fallbackClassName, children: message }) : message;
2879
+ return this.props.fallbackClassName ? /* @__PURE__ */ jsx41("div", { className: this.props.fallbackClassName, children: message }) : message;
2719
2880
  }
2720
2881
  };
2721
2882
 
2722
2883
  // src/ProgressBar.tsx
2723
2884
  import { Progress } from "@base-ui/react/progress";
2724
- import { jsx as jsx41 } from "react/jsx-runtime";
2885
+ import { jsx as jsx42 } from "react/jsx-runtime";
2725
2886
  var TRACK_CLASSES = {
2726
2887
  default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
2727
2888
  // 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
@@ -2734,18 +2895,18 @@ var INDICATOR_CLASSES = {
2734
2895
  function ProgressBar({ value, max, label, variant = "default", className }) {
2735
2896
  return (
2736
2897
  // `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
2737
- /* @__PURE__ */ jsx41(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx41(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx41(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
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] }) }) })
2738
2899
  );
2739
2900
  }
2740
2901
 
2741
2902
  // src/Breadcrumb.tsx
2742
- import { Fragment as Fragment10, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as useRef8, useState as useState6 } from "react";
2743
- import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
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";
2744
2905
  function Breadcrumb({ items, className }) {
2745
- const navRef = useRef8(null);
2746
- const labelRefs = useRef8([]);
2747
- const [truncated, setTruncated] = useState6(/* @__PURE__ */ new Set());
2748
- const measure = useCallback2(() => {
2906
+ const navRef = useRef9(null);
2907
+ const labelRefs = useRef9([]);
2908
+ const [truncated, setTruncated] = useState7(/* @__PURE__ */ new Set());
2909
+ const measure = useCallback3(() => {
2749
2910
  const next = /* @__PURE__ */ new Set();
2750
2911
  labelRefs.current.forEach((el, index) => {
2751
2912
  if (el && el.scrollWidth > el.clientWidth) next.add(index);
@@ -2760,7 +2921,7 @@ function Breadcrumb({ items, className }) {
2760
2921
  observer.observe(nav);
2761
2922
  return () => observer.disconnect();
2762
2923
  }, [measure, items]);
2763
- return /* @__PURE__ */ jsx42("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) => {
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) => {
2764
2925
  const last = index === items.length - 1;
2765
2926
  const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
2766
2927
  const text = cn(
@@ -2781,34 +2942,34 @@ function Breadcrumb({ items, className }) {
2781
2942
  // on a box around it, which the link takes them from, rather than
2782
2943
  // pushed into it (UIG-9); the link is still the one element that
2783
2944
  // truncates and is measured.
2784
- /* @__PURE__ */ jsx42("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx42(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
2785
- ) : /* @__PURE__ */ jsx42("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
2786
- return /* @__PURE__ */ jsxs28(Fragment10, { children: [
2787
- index > 0 && /* @__PURE__ */ jsx42("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
2788
- item.icon && /* @__PURE__ */ jsx42("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
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 }),
2789
2950
  truncated.has(index) ? (
2790
2951
  // `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
2791
2952
  // must keep truncating inside it, or wrapping it would widen the
2792
2953
  // trail and the tooltip would never be needed again.
2793
- /* @__PURE__ */ jsx42(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
2954
+ /* @__PURE__ */ jsx43(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
2794
2955
  ) : crumb
2795
2956
  ] }, `${item.label}-${index}`);
2796
2957
  }) });
2797
2958
  }
2798
2959
 
2799
2960
  // src/NavItem.tsx
2800
- import { useId, useState as useState7 } from "react";
2961
+ import { useId, useState as useState8 } from "react";
2801
2962
  import { Collapsible } from "@base-ui/react/collapsible";
2802
2963
  import { IconAlertSquareRounded, IconChevronRight as IconChevronRight2, IconDotsVertical } from "@tabler/icons-react";
2803
2964
 
2804
2965
  // src/UnreadDot.tsx
2805
- import { jsx as jsx43 } from "react/jsx-runtime";
2966
+ import { jsx as jsx44 } from "react/jsx-runtime";
2806
2967
  function UnreadDot({ className }) {
2807
- return /* @__PURE__ */ jsx43("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx43("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
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" }) });
2808
2969
  }
2809
2970
 
2810
2971
  // src/NavItem.tsx
2811
- import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2972
+ import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
2812
2973
  function NavItem({
2813
2974
  label,
2814
2975
  href,
@@ -2828,7 +2989,7 @@ function NavItem({
2828
2989
  className,
2829
2990
  ...props
2830
2991
  }) {
2831
- const [openState, setOpenState] = useState7(defaultOpen);
2992
+ const [openState, setOpenState] = useState8(defaultOpen);
2832
2993
  const panelId = useId();
2833
2994
  const hasRows = children != null && children !== false;
2834
2995
  const open = openProp ?? openState;
@@ -2837,9 +2998,9 @@ function NavItem({
2837
2998
  onOpenChange?.(next);
2838
2999
  };
2839
3000
  const besides = menu != null || hasRows;
2840
- const mark = unread ? urgent ? /* @__PURE__ */ jsx44(UrgentMark, {}) : /* @__PURE__ */ jsx44(UnreadDot, {}) : null;
2841
- const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-focus-within/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0";
2842
- const row = /* @__PURE__ */ jsxs29(
3001
+ const mark = unread ? urgent ? /* @__PURE__ */ jsx45(UrgentMark, {}) : /* @__PURE__ */ jsx45(UnreadDot, {}) : null;
3002
+ 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";
3003
+ const row = /* @__PURE__ */ jsxs30(
2843
3004
  "a",
2844
3005
  {
2845
3006
  href,
@@ -2860,21 +3021,21 @@ function NavItem({
2860
3021
  ),
2861
3022
  ...props,
2862
3023
  children: [
2863
- (icon || hasRows) && /* @__PURE__ */ jsx44(
3024
+ (icon || hasRows) && /* @__PURE__ */ jsx45(
2864
3025
  "span",
2865
3026
  {
2866
3027
  className: cn(
2867
3028
  // With rows under it the slot is kept even with no icon: the arrow lands in it.
2868
3029
  "flex min-w-4 shrink-0 items-center",
2869
- hasRows && "transition-opacity group-hover/nav:opacity-0 group-focus-within/nav:opacity-0"
3030
+ hasRows && "transition-opacity group-hover/nav:opacity-0 group-has-[:focus-visible]/nav:opacity-0"
2870
3031
  ),
2871
3032
  children: icon
2872
3033
  }
2873
3034
  ),
2874
- /* @__PURE__ */ jsx44("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
3035
+ /* @__PURE__ */ jsx45("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
2875
3036
  hint != null && // Takes room only while it shows, so the label gives way to it.
2876
- /* @__PURE__ */ jsx44("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-focus-within/nav:flex", children: hint }),
2877
- count ? /* @__PURE__ */ jsx44(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx44(
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(
2878
3039
  "span",
2879
3040
  {
2880
3041
  className: cn(
@@ -2885,22 +3046,27 @@ function NavItem({
2885
3046
  children: count
2886
3047
  }
2887
3048
  ) }) : null,
2888
- mark ? /* @__PURE__ */ jsx44("span", { className: cn("flex shrink-0", stepsAside), children: mark }) : menu != null && !count ? (
3049
+ mark ? (
3050
+ // `-mr-1`: the 24px slot's dot then sits on the axis of a count and
3051
+ // of the ⋮ (8px from the edge to the 16px box), one column with a
3052
+ // folder heading's dot and ⋮ (Katerina, 5 October).
3053
+ /* @__PURE__ */ jsx45("span", { className: cn("-mr-1 flex shrink-0", stepsAside), children: mark })
3054
+ ) : menu != null && !count ? (
2889
3055
  // Nothing at the right, but a menu: no room is kept at rest, so the
2890
3056
  // label has the row's whole width; while the ⋮ shows, its 24px slot
2891
3057
  // is kept, so a long label ends before it instead of running under it.
2892
- /* @__PURE__ */ jsx44("span", { "aria-hidden": "true", className: "hidden w-6 shrink-0 group-hover/nav:block group-focus-within/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block" })
3058
+ /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "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" })
2893
3059
  ) : null
2894
3060
  ]
2895
3061
  }
2896
3062
  );
2897
3063
  if (!besides && hint == null) return row;
2898
3064
  const name = menuLabel ?? `More options for ${label}`;
2899
- const line = /* @__PURE__ */ jsxs29("div", { className: "group/nav relative shrink-0", children: [
3065
+ const line = /* @__PURE__ */ jsxs30("div", { className: "group/nav relative shrink-0", children: [
2900
3066
  row,
2901
3067
  hasRows && // `left-1`: the 24px button's 16px arrow then sits where the icon
2902
3068
  // sits (the row's px-2), so the icon turns into the arrow in place.
2903
- /* @__PURE__ */ jsx44("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity focus-within:opacity-100 group-hover/nav:opacity-100", children: /* @__PURE__ */ jsx44(
3069
+ /* @__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(
2904
3070
  IconButton,
2905
3071
  {
2906
3072
  tooltip: open ? "Collapse" : "Expand",
@@ -2908,77 +3074,95 @@ function NavItem({
2908
3074
  "aria-expanded": open,
2909
3075
  "aria-controls": panelId,
2910
3076
  onClick: () => setOpen(!open),
2911
- children: /* @__PURE__ */ jsx44(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
3077
+ children: /* @__PURE__ */ jsx45(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
2912
3078
  }
2913
3079
  ) }),
2914
- menu != null && // On a count, `right-1`: the 24px button's 16px icon then ends 8px
2915
- // from the row's edge, where the count ends (px-2), so the ⋮ lands on
2916
- // the number. On the mark or the empty slot, `right-2`: the button
2917
- // sits in the 24px slot itself.
2918
- /* @__PURE__ */ jsx44("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 flex items-center", count && !mark ? "right-1" : "right-2", "opacity-0 transition-opacity focus-within:opacity-100 group-hover/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100"), children: /* @__PURE__ */ jsx44(
3080
+ menu != null && // `right-1`: the 24px button's 16px icon ends 8px from the row's
3081
+ // edge, where a count ends (px-2) — and where a SectionHeader's
3082
+ // actions and ⋮ end, so a folder's ⋮ and its rows' ⋮ are one column
3083
+ // (Katerina, 5 October: the rows move to the heading, not the
3084
+ // heading to the rows). Over a dot or the empty slot it sits 4px
3085
+ // right of the slot's centre.
3086
+ /* @__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"), children: /* @__PURE__ */ jsx45(
2919
3087
  Menu,
2920
3088
  {
2921
3089
  align: "right",
2922
- trigger: /* @__PURE__ */ jsx44(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx44(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
3090
+ trigger: /* @__PURE__ */ jsx45(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx45(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
2923
3091
  children: menu
2924
3092
  }
2925
3093
  ) })
2926
3094
  ] });
2927
3095
  if (!hasRows) return line;
2928
- return /* @__PURE__ */ jsxs29(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
3096
+ return /* @__PURE__ */ jsxs30(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
2929
3097
  line,
2930
- /* @__PURE__ */ jsx44(
3098
+ /* @__PURE__ */ jsx45(
2931
3099
  Collapsible.Panel,
2932
3100
  {
2933
3101
  id: panelId,
2934
3102
  hiddenUntilFound: true,
2935
3103
  className: COLLAPSIBLE_PANEL_CLASSES,
2936
- children: /* @__PURE__ */ jsx44("div", { className: "flex flex-col gap-px pl-6", children })
3104
+ children: /* @__PURE__ */ jsx45("div", { className: "flex flex-col gap-0.5 pt-0.5 pl-6", children })
2937
3105
  }
2938
3106
  )
2939
3107
  ] });
2940
3108
  }
2941
3109
  function UrgentMark() {
2942
- return /* @__PURE__ */ jsx44("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx44("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx44(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
3110
+ 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" }) }) });
2943
3111
  }
2944
3112
 
2945
3113
  // src/NavTree.tsx
2946
- import { useEffect as useEffect4, useRef as useRef9 } from "react";
3114
+ import { useEffect as useEffect5, useRef as useRef10 } from "react";
2947
3115
 
2948
3116
  // src/CollapsibleSection.tsx
2949
- import { useState as useState8 } from "react";
3117
+ import { useState as useState9 } from "react";
2950
3118
  import { Collapsible as Collapsible2 } from "@base-ui/react/collapsible";
2951
3119
 
2952
3120
  // src/SectionHeader.tsx
2953
- import { IconChevronRight as IconChevronRight3 } from "@tabler/icons-react";
3121
+ import { isValidElement as isValidElement2 } from "react";
3122
+ import { IconChevronRight as IconChevronRight3, IconDotsVertical as IconDotsVertical2 } from "@tabler/icons-react";
2954
3123
  import { useRender } from "@base-ui/react/use-render";
2955
- import { Fragment as Fragment11, jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
2956
- function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", look = "heading", render, className }) {
3124
+ import { Fragment as Fragment11, jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
3125
+ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onToggle, trailing, actions, menu, menuLabel, showActions = "hover", hover = "fill", look = "heading", render, className }) {
2957
3126
  const row = look === "row";
3127
+ const acts = actions && actions.length > 0 || menu != null;
3128
+ const dot = isValidElement2(trailing) && trailing.type === UnreadDot;
3129
+ const shared = acts && showActions === "hover" && dot;
3130
+ const reveal = showActions === "hover" && "opacity-0 transition-opacity group-hover:opacity-100 has-[:focus-visible]:opacity-100 has-[[aria-expanded=true]]:opacity-100";
2958
3131
  const titleElement = useRender({
2959
- render: render ?? (chevron ? /* @__PURE__ */ jsx45("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx45("span", {})),
3132
+ render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
2960
3133
  props: {
2961
3134
  // `text-left`: a button centres its text. `h-full` and `flex-1`: the
2962
3135
  // whole row up to the actions is the hit target, as it was when the
2963
3136
  // row itself carried the click.
2964
- className: cn("flex h-full min-w-0 flex-1 items-center text-left", row ? "gap-2" : "gap-1"),
2965
- children: /* @__PURE__ */ jsxs30(Fragment11, { children: [
2966
- chevron && /* @__PURE__ */ jsx45(
3137
+ // An icon is a row's: NavItem's 8px after it.
3138
+ className: cn("flex h-full min-w-0 flex-1 items-center text-left", row || chevron || icon != null ? "gap-2" : "gap-1"),
3139
+ children: /* @__PURE__ */ jsxs31(Fragment11, { children: [
3140
+ icon != null ? /* @__PURE__ */ jsxs31("span", { className: "relative flex size-4 shrink-0 items-center justify-center text-text-secondary", children: [
3141
+ /* @__PURE__ */ jsx46("span", { className: cn("flex", chevron && "transition-opacity group-hover:opacity-0 group-has-[:focus-visible]:opacity-0"), children: icon }),
3142
+ chevron && /* @__PURE__ */ jsx46(
3143
+ IconChevronRight3,
3144
+ {
3145
+ size: 16,
3146
+ stroke: 1.5,
3147
+ className: cn("absolute opacity-0 transition-[opacity,transform] duration-150 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100", isExpanded && "rotate-90")
3148
+ }
3149
+ )
3150
+ ] }) : chevron && /* @__PURE__ */ jsx46(
2967
3151
  IconChevronRight3,
2968
3152
  {
2969
- size: row ? 16 : 12,
3153
+ size: 16,
2970
3154
  stroke: 1.5,
2971
3155
  className: cn("shrink-0 transition-transform duration-150", !row && "text-text-secondary", isExpanded && "rotate-90")
2972
3156
  }
2973
3157
  ),
2974
- look === "quiet" ? /* @__PURE__ */ jsx45("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
3158
+ look === "quiet" ? /* @__PURE__ */ jsx46("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
2975
3159
  // A row's words: NavItem's size and colour, brightening under the pointer with the row.
2976
- /* @__PURE__ */ jsx45("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
2977
- ) : /* @__PURE__ */ jsx45(SectionLabel, { folds: chevron, children: title })
3160
+ /* @__PURE__ */ jsx46("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
3161
+ ) : /* @__PURE__ */ jsx46(SectionLabel, { folds: chevron, children: title })
2978
3162
  ] })
2979
3163
  }
2980
3164
  });
2981
- return /* @__PURE__ */ jsxs30(
3165
+ return /* @__PURE__ */ jsxs31(
2982
3166
  "div",
2983
3167
  {
2984
3168
  className: cn(
@@ -2990,20 +3174,37 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2990
3174
  // lights up, a fixed heading over rows does not (2026-09-09, the
2991
3175
  // Sidebar's fixed group).
2992
3176
  // A quiet label never lights up: it is a label; its button does.
2993
- hover === "fill" && look !== "quiet" && (chevron || actions && actions.length > 0) && "hover:bg-bg-hover",
3177
+ hover === "fill" && look !== "quiet" && (chevron || acts) && "hover:bg-bg-hover",
3178
+ // While its menu is open the pointer is on the menu, not the row: the
3179
+ // row keeps its hover look, as a NavItem's does.
3180
+ hover === "fill" && look !== "quiet" && menu != null && "has-[[data-section-menu]_[aria-expanded=true]]:bg-bg-hover",
2994
3181
  className
2995
3182
  ),
2996
3183
  children: [
2997
3184
  titleElement,
2998
- trailing != null && /* @__PURE__ */ jsx45("div", { className: "flex shrink-0 items-center", children: trailing }),
2999
- actions && actions.length > 0 && /* @__PURE__ */ jsx45(
3185
+ trailing != null && !shared && // A dot with no buttons to share a place with still sits on their
3186
+ // axis — the rows' dots and ⋮ (`-mr-1`, as the buttons are pulled).
3187
+ /* @__PURE__ */ jsx46("div", { className: cn("flex shrink-0 items-center", dot && !acts && "-mr-1"), children: trailing }),
3188
+ acts && /* @__PURE__ */ jsxs31(
3000
3189
  "div",
3001
3190
  {
3002
- className: cn(
3003
- "-mr-1 flex shrink-0 items-center gap-1",
3004
- showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
3005
- ),
3006
- children: actions.map((action) => /* @__PURE__ */ jsx45(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
3191
+ className: "group/acts relative -mr-1 flex shrink-0 items-center",
3192
+ children: [
3193
+ /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center gap-1", reveal), children: [
3194
+ actions?.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3195
+ menu != null && /* @__PURE__ */ jsx46("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx46(
3196
+ Menu,
3197
+ {
3198
+ align: "right",
3199
+ trigger: /* @__PURE__ */ jsx46(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx46(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3200
+ children: menu
3201
+ }
3202
+ ) })
3203
+ ] }),
3204
+ shared && // The dot in the last button's 24px place, on the axis of its icon;
3205
+ // gone while the buttons show.
3206
+ /* @__PURE__ */ jsx46("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex w-6 items-center justify-center transition-opacity group-hover:opacity-0 group-has-[:focus-visible]/acts:opacity-0 group-has-[[aria-expanded=true]]/acts:opacity-0", children: trailing })
3207
+ ]
3007
3208
  }
3008
3209
  )
3009
3210
  ]
@@ -3012,7 +3213,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
3012
3213
  }
3013
3214
 
3014
3215
  // src/CollapsibleSection.tsx
3015
- import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
3216
+ import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
3016
3217
  var OPEN = "open";
3017
3218
  var CLOSED = "closed";
3018
3219
  function readStored(key) {
@@ -3031,39 +3232,39 @@ function writeStored(key, open) {
3031
3232
  } catch {
3032
3233
  }
3033
3234
  }
3034
- function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, look = "heading", indent = false, children, className, contentClassName }) {
3035
- const [openState, setOpenState] = useState8(() => readStored(storageKey) ?? defaultOpen);
3235
+ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, icon, trailing, actions, menu, menuLabel, showActions, look = "heading", indent = false, children, className, contentClassName }) {
3236
+ const [openState, setOpenState] = useState9(() => readStored(storageKey) ?? defaultOpen);
3036
3237
  const open = openProp ?? openState;
3037
3238
  const setOpen = (next) => {
3038
3239
  setOpenState(next);
3039
3240
  writeStored(storageKey, next);
3040
3241
  onOpenChange?.(next);
3041
3242
  };
3042
- return /* @__PURE__ */ jsxs31(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
3043
- /* @__PURE__ */ jsx46(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx46(Collapsible2.Trigger, {}) }),
3044
- /* @__PURE__ */ jsx46(
3243
+ return /* @__PURE__ */ jsxs32(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
3244
+ /* @__PURE__ */ jsx47(SectionHeader, { title, chevron: true, icon, isExpanded: open, trailing, actions, menu, menuLabel, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx47(Collapsible2.Trigger, {}) }),
3245
+ /* @__PURE__ */ jsx47(
3045
3246
  Collapsible2.Panel,
3046
3247
  {
3047
3248
  hiddenUntilFound: true,
3048
3249
  className: COLLAPSIBLE_PANEL_CLASSES,
3049
- children: /* @__PURE__ */ jsx46("div", { className: cn("flex flex-col", look === "row" ? "pl-6" : indent && "pl-4", contentClassName), children })
3250
+ children: /* @__PURE__ */ jsx47("div", { className: cn("flex flex-col pt-0.5", (look === "row" || indent) && "pl-6", contentClassName), children })
3050
3251
  }
3051
3252
  )
3052
3253
  ] });
3053
3254
  }
3054
3255
 
3055
3256
  // src/NavTree.tsx
3056
- import { Fragment as Fragment12, jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
3257
+ import { Fragment as Fragment12, jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
3057
3258
  var NAV_TREE_INTENT_MS = 150;
3058
3259
  function holds(nodes, id) {
3059
3260
  return !!nodes && id !== void 0 && nodes.some((node) => node.id === id || holds(node.children ?? null, id));
3060
3261
  }
3061
3262
  function Line({ message }) {
3062
- return /* @__PURE__ */ jsx47("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx47(EmptyState, { scope: "section", message }) });
3263
+ return /* @__PURE__ */ jsx48("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx48(EmptyState, { scope: "section", message }) });
3063
3264
  }
3064
3265
  function Row({ node, selected, onSelect }) {
3065
- const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx47(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx47(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx47(SkeletonList, { rows: 2 }) : void 0;
3066
- return /* @__PURE__ */ jsx47(
3266
+ 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;
3267
+ return /* @__PURE__ */ jsx48(
3067
3268
  NavItem,
3068
3269
  {
3069
3270
  href: node.href,
@@ -3085,7 +3286,7 @@ function Row({ node, selected, onSelect }) {
3085
3286
  );
3086
3287
  }
3087
3288
  function Group({ group, selected, onSelect, storageKey }) {
3088
- return /* @__PURE__ */ jsx47(
3289
+ return /* @__PURE__ */ jsx48(
3089
3290
  NavTreeSection,
3090
3291
  {
3091
3292
  id: group.id,
@@ -3094,23 +3295,25 @@ function Group({ group, selected, onSelect, storageKey }) {
3094
3295
  loading: group.nodes === null,
3095
3296
  trailing: group.trailing,
3096
3297
  actions: group.actions,
3298
+ menu: group.menu,
3299
+ icon: group.icon,
3097
3300
  defaultOpen: group.defaultOpen ?? holds(group.nodes, selected),
3098
3301
  open: group.open,
3099
3302
  onOpenChange: group.onOpenChange,
3100
3303
  storageKey: storageKey ? `${storageKey}.${group.id}` : void 0,
3101
3304
  onIntent: group.onIntent,
3102
- children: group.nodes?.map((node) => /* @__PURE__ */ jsx47(Row, { node, selected, onSelect }, node.id))
3305
+ children: group.nodes?.map((node) => /* @__PURE__ */ jsx48(Row, { node, selected, onSelect }, node.id))
3103
3306
  }
3104
3307
  );
3105
3308
  }
3106
- function NavTreeSection({ id, title, message, loading = false, trailing, actions, defaultOpen = true, open, onOpenChange, storageKey, onIntent, children }) {
3107
- const timer = useRef9(void 0);
3108
- useEffect4(() => () => clearTimeout(timer.current), []);
3309
+ function NavTreeSection({ id, title, message, loading = false, trailing, actions, menu, icon, defaultOpen = true, open, onOpenChange, storageKey, onIntent, children }) {
3310
+ const timer = useRef10(void 0);
3311
+ useEffect5(() => () => clearTimeout(timer.current), []);
3109
3312
  const intent = onIntent;
3110
- return /* @__PURE__ */ jsx47(
3313
+ return /* @__PURE__ */ jsx48(
3111
3314
  "div",
3112
3315
  {
3113
- className: "shrink-0",
3316
+ className: "mt-1 shrink-0 first:mt-0",
3114
3317
  "data-nav-group": id,
3115
3318
  onPointerEnter: intent ? () => {
3116
3319
  clearTimeout(timer.current);
@@ -3118,7 +3321,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3118
3321
  } : void 0,
3119
3322
  onPointerLeave: intent ? () => clearTimeout(timer.current) : void 0,
3120
3323
  onFocus: intent,
3121
- children: /* @__PURE__ */ jsx47(
3324
+ children: /* @__PURE__ */ jsx48(
3122
3325
  CollapsibleSection,
3123
3326
  {
3124
3327
  title,
@@ -3129,28 +3332,30 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3129
3332
  storageKey,
3130
3333
  trailing,
3131
3334
  actions,
3132
- className: "mt-2 shrink-0",
3133
- contentClassName: "gap-px",
3134
- children: message !== void 0 ? /* @__PURE__ */ jsx47(Line, { message }) : loading ? /* @__PURE__ */ jsx47(SkeletonList, { rows: 3 }) : children
3335
+ menu,
3336
+ icon,
3337
+ className: "shrink-0",
3338
+ contentClassName: "gap-0.5",
3339
+ children: message !== void 0 ? /* @__PURE__ */ jsx48(Line, { message }) : loading ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 3 }) : children
3135
3340
  }
3136
3341
  )
3137
3342
  }
3138
3343
  );
3139
3344
  }
3140
3345
  function NavTree({ title, titleActions, groups, children, selected, onSelect, emptyMessage = "", storageKey }) {
3141
- return /* @__PURE__ */ jsxs32(Fragment12, { children: [
3142
- title && /* @__PURE__ */ jsx47(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
3143
- groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx47(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
3346
+ return /* @__PURE__ */ jsxs33(Fragment12, { children: [
3347
+ title && /* @__PURE__ */ jsx48(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
3348
+ groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
3144
3349
  // No words, no line: an app that says nothing when it has no groups.
3145
- emptyMessage ? /* @__PURE__ */ jsx47(Line, { message: emptyMessage }) : null
3146
- ) : groups.map((group) => /* @__PURE__ */ jsx47(Group, { group, selected, onSelect, storageKey }, group.id))
3350
+ emptyMessage ? /* @__PURE__ */ jsx48(Line, { message: emptyMessage }) : null
3351
+ ) : groups.map((group) => /* @__PURE__ */ jsx48(Group, { group, selected, onSelect, storageKey }, group.id))
3147
3352
  ] });
3148
3353
  }
3149
3354
 
3150
3355
  // src/Popover.tsx
3151
3356
  import { useMemo as useMemo3 } from "react";
3152
3357
  import { Popover as BasePopover } from "@base-ui/react/popover";
3153
- import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
3358
+ import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
3154
3359
  var GAP5 = 4;
3155
3360
  var VIEWPORT_PAD5 = 8;
3156
3361
  function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
@@ -3159,7 +3364,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3159
3364
  if (anchor instanceof Element) return anchor;
3160
3365
  return { getBoundingClientRect: () => anchor };
3161
3366
  }, [anchor]);
3162
- return /* @__PURE__ */ jsxs33(
3367
+ return /* @__PURE__ */ jsxs34(
3163
3368
  BasePopover.Root,
3164
3369
  {
3165
3370
  open,
@@ -3167,8 +3372,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3167
3372
  actionsRef,
3168
3373
  modal: false,
3169
3374
  children: [
3170
- trigger && /* @__PURE__ */ jsx48(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
3171
- /* @__PURE__ */ jsx48(BasePopover.Portal, { children: /* @__PURE__ */ jsx48(
3375
+ trigger && /* @__PURE__ */ jsx49(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
3376
+ /* @__PURE__ */ jsx49(BasePopover.Portal, { children: /* @__PURE__ */ jsx49(
3172
3377
  BasePopover.Positioner,
3173
3378
  {
3174
3379
  anchor: anchorTarget,
@@ -3177,20 +3382,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3177
3382
  sideOffset: GAP5,
3178
3383
  collisionPadding: VIEWPORT_PAD5,
3179
3384
  className: "z-50 data-[anchor-hidden]:hidden",
3180
- children: /* @__PURE__ */ jsx48(
3385
+ children: /* @__PURE__ */ jsx49(
3181
3386
  BasePopover.Popup,
3182
3387
  {
3183
3388
  "aria-label": ariaLabel,
3184
3389
  initialFocus: trigger ? void 0 : false,
3185
3390
  finalFocus,
3186
3391
  className: cn("min-w-[180px] outline-none p-0", className),
3187
- render: /* @__PURE__ */ jsx48(MenuPanel, {}),
3188
- children: /* @__PURE__ */ jsx48(
3392
+ render: /* @__PURE__ */ jsx49(MenuPanel, {}),
3393
+ children: /* @__PURE__ */ jsx49(
3189
3394
  ScrollArea,
3190
3395
  {
3191
3396
  viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
3192
3397
  contentClassName: cn("flex flex-col p-2", contentClassName),
3193
- children: /* @__PURE__ */ jsx48(DividerInPanel.Provider, { value: true, children })
3398
+ children: /* @__PURE__ */ jsx49(DividerInPanel.Provider, { value: true, children })
3194
3399
  }
3195
3400
  )
3196
3401
  }
@@ -3203,18 +3408,18 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3203
3408
  }
3204
3409
 
3205
3410
  // src/SuggestionMenu.tsx
3206
- import { useCallback as useCallback3, useEffect as useEffect5, useId as useId2, useImperativeHandle, useMemo as useMemo4, useRef as useRef10, useState as useState9 } from "react";
3207
- import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
3411
+ import { useCallback as useCallback4, useEffect as useEffect6, useId as useId2, useImperativeHandle, useMemo as useMemo4, useRef as useRef11, useState as useState10 } from "react";
3412
+ import { jsx as jsx50, jsxs as jsxs35 } from "react/jsx-runtime";
3208
3413
  function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sections, itemKey, row, onSelect, handle }) {
3209
3414
  const shown = useMemo4(() => sections.filter((section) => section.items.length > 0), [sections]);
3210
3415
  const items = useMemo4(() => shown.flatMap((section) => section.items), [shown]);
3211
3416
  const keys = items.map(itemKey).join("\n");
3212
- const [highlight, setHighlight] = useState9(0);
3417
+ const [highlight, setHighlight] = useState10(0);
3213
3418
  const base = useId2();
3214
3419
  const listboxId = `${base}-list`;
3215
- const chosen = useRef10(null);
3216
- useEffect5(() => void (chosen.current = highlight > 0 ? keys.split("\n")[highlight] ?? null : null), [highlight]);
3217
- useEffect5(() => {
3420
+ const chosen = useRef11(null);
3421
+ useEffect6(() => void (chosen.current = highlight > 0 ? keys.split("\n")[highlight] ?? null : null), [highlight]);
3422
+ useEffect6(() => {
3218
3423
  const at = chosen.current ? keys.split("\n").indexOf(chosen.current) : -1;
3219
3424
  setHighlight(at > 0 ? at : 0);
3220
3425
  }, [keys]);
@@ -3239,7 +3444,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3239
3444
  }
3240
3445
  }), [items, highlight, onSelect]);
3241
3446
  const open = rect !== null && items.length > 0;
3242
- useEffect5(() => {
3447
+ useEffect6(() => {
3243
3448
  if (!editorElement || !open) return;
3244
3449
  editorElement.setAttribute("aria-autocomplete", "list");
3245
3450
  editorElement.setAttribute("aria-haspopup", "listbox");
@@ -3248,11 +3453,11 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3248
3453
  for (const name of ["aria-autocomplete", "aria-haspopup", "aria-controls", "aria-activedescendant"]) editorElement.removeAttribute(name);
3249
3454
  };
3250
3455
  }, [editorElement, open, listboxId]);
3251
- useEffect5(() => {
3456
+ useEffect6(() => {
3252
3457
  if (!editorElement || !open) return;
3253
3458
  editorElement.setAttribute("aria-activedescendant", `${base}-${highlight}`);
3254
3459
  }, [editorElement, open, base, highlight]);
3255
- const scrollRef = useCallback3((el) => {
3460
+ const scrollRef = useCallback4((el) => {
3256
3461
  el?.scrollIntoView({ block: "nearest" });
3257
3462
  }, []);
3258
3463
  if (items.length === 0) return null;
@@ -3262,7 +3467,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3262
3467
  const { label, description, leading, shortcut, hint, size } = row(item);
3263
3468
  return (
3264
3469
  // A row of a list the editor drives from its caret: focus stays in the text, so the row is no Tab stop.
3265
- /* @__PURE__ */ jsx49(
3470
+ /* @__PURE__ */ jsx50(
3266
3471
  MenuItem,
3267
3472
  {
3268
3473
  role: "option",
@@ -3287,17 +3492,17 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3287
3492
  )
3288
3493
  );
3289
3494
  };
3290
- return /* @__PURE__ */ jsx49(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, children: /* @__PURE__ */ jsx49("div", { id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col", children: shown.map((section, i) => /* @__PURE__ */ jsxs34("div", { className: "contents", children: [
3291
- i > 0 && /* @__PURE__ */ jsx49(MenuSeparator, {}),
3292
- section.label ? /* @__PURE__ */ jsx49("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx49(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
3495
+ return /* @__PURE__ */ jsx50(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, children: /* @__PURE__ */ jsx50("div", { id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col", children: shown.map((section, i) => /* @__PURE__ */ jsxs35("div", { className: "contents", children: [
3496
+ i > 0 && /* @__PURE__ */ jsx50(MenuSeparator, {}),
3497
+ 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)
3293
3498
  ] }, section.label ?? i)) }) });
3294
3499
  }
3295
3500
 
3296
3501
  // src/Toolbar.tsx
3297
3502
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
3298
- import { jsx as jsx50 } from "react/jsx-runtime";
3503
+ import { jsx as jsx51 } from "react/jsx-runtime";
3299
3504
  function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
3300
- const strip = /* @__PURE__ */ jsx50(
3505
+ const strip = /* @__PURE__ */ jsx51(
3301
3506
  BaseToolbar.Root,
3302
3507
  {
3303
3508
  "aria-label": ariaLabel,
@@ -3308,27 +3513,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
3308
3513
  }
3309
3514
  );
3310
3515
  if (!surface) return strip;
3311
- return /* @__PURE__ */ jsx50(MenuPanel, { className: "w-fit p-1", children: strip });
3516
+ return /* @__PURE__ */ jsx51(MenuPanel, { className: "w-fit p-1", children: strip });
3312
3517
  }
3313
3518
  function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
3314
- return /* @__PURE__ */ jsx50(
3519
+ return /* @__PURE__ */ jsx51(
3315
3520
  BaseToolbar.Button,
3316
3521
  {
3317
3522
  ref,
3318
3523
  disabled: disabled || !!disabledReason,
3319
3524
  focusableWhenDisabled: true,
3320
- render: /* @__PURE__ */ jsx50(IconButton, { disabled, disabledReason, ...props })
3525
+ render: /* @__PURE__ */ jsx51(IconButton, { disabled, disabledReason, ...props })
3321
3526
  }
3322
3527
  );
3323
3528
  }
3324
3529
  function ToolbarLink({ ref, href, ...props }) {
3325
- return /* @__PURE__ */ jsx50(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx50(IconButton, { href, ...props }) });
3530
+ return /* @__PURE__ */ jsx51(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx51(IconButton, { href, ...props }) });
3326
3531
  }
3327
3532
  function ToolbarInput({ size, ...props }) {
3328
- return /* @__PURE__ */ jsx50(BaseToolbar.Input, { render: /* @__PURE__ */ jsx50(TextInput, { size }), ...props });
3533
+ return /* @__PURE__ */ jsx51(BaseToolbar.Input, { render: /* @__PURE__ */ jsx51(TextInput, { size }), ...props });
3329
3534
  }
3330
3535
  function ToolbarSeparator({ className }) {
3331
- return /* @__PURE__ */ jsx50(
3536
+ return /* @__PURE__ */ jsx51(
3332
3537
  BaseToolbar.Separator,
3333
3538
  {
3334
3539
  orientation: "vertical",
@@ -3338,9 +3543,9 @@ function ToolbarSeparator({ className }) {
3338
3543
  }
3339
3544
 
3340
3545
  // src/ReactionPicker.tsx
3341
- import { jsx as jsx51 } from "react/jsx-runtime";
3546
+ import { jsx as jsx52 } from "react/jsx-runtime";
3342
3547
  function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
3343
- return /* @__PURE__ */ jsx51(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
3548
+ return /* @__PURE__ */ jsx52(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
3344
3549
  /*
3345
3550
  A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
3346
3551
  would become the toolbar's item and the button inside it would never
@@ -3350,14 +3555,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
3350
3555
  The tooltip names it for a pointer, `aria-label` for everything else,
3351
3556
  and both say the meaning rather than the glyph.
3352
3557
  */
3353
- /* @__PURE__ */ jsx51(
3558
+ /* @__PURE__ */ jsx52(
3354
3559
  ToolbarButton,
3355
3560
  {
3356
3561
  "aria-label": option.label,
3357
3562
  tooltip: option.label,
3358
3563
  onClick: () => onSelect(option.emoji),
3359
3564
  className: "size-7",
3360
- children: /* @__PURE__ */ jsx51("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
3565
+ children: /* @__PURE__ */ jsx52("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
3361
3566
  },
3362
3567
  option.emoji
3363
3568
  )
@@ -3366,23 +3571,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
3366
3571
 
3367
3572
  // src/PreviewCard.tsx
3368
3573
  import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
3369
- import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
3574
+ import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
3370
3575
  var GAP6 = 12;
3371
3576
  var VIEWPORT_PAD6 = 8;
3372
3577
  var OPEN_DELAY2 = 350;
3373
3578
  var CLOSE_DELAY = 200;
3374
3579
  function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
3375
- return /* @__PURE__ */ jsxs35(BasePreviewCard.Root, { children: [
3376
- /* @__PURE__ */ jsx52(
3580
+ return /* @__PURE__ */ jsxs36(BasePreviewCard.Root, { children: [
3581
+ /* @__PURE__ */ jsx53(
3377
3582
  BasePreviewCard.Trigger,
3378
3583
  {
3379
3584
  delay,
3380
3585
  closeDelay,
3381
- render: /* @__PURE__ */ jsx52("span", { className: cn("inline-flex", wrapperClassName) }),
3586
+ render: /* @__PURE__ */ jsx53("span", { className: cn("inline-flex", wrapperClassName) }),
3382
3587
  children
3383
3588
  }
3384
3589
  ),
3385
- /* @__PURE__ */ jsx52(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx52(
3590
+ /* @__PURE__ */ jsx53(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx53(
3386
3591
  BasePreviewCard.Positioner,
3387
3592
  {
3388
3593
  side,
@@ -3390,12 +3595,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
3390
3595
  sideOffset: GAP6,
3391
3596
  collisionPadding: VIEWPORT_PAD6,
3392
3597
  className: "z-50 data-[anchor-hidden]:hidden",
3393
- children: /* @__PURE__ */ jsx52(
3598
+ children: /* @__PURE__ */ jsx53(
3394
3599
  BasePreviewCard.Popup,
3395
3600
  {
3396
3601
  className: cn("w-[360px] p-0 outline-none", className),
3397
- render: /* @__PURE__ */ jsx52(MenuPanel, {}),
3398
- children: /* @__PURE__ */ jsx52(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
3602
+ render: /* @__PURE__ */ jsx53(MenuPanel, {}),
3603
+ children: /* @__PURE__ */ jsx53(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
3399
3604
  }
3400
3605
  )
3401
3606
  }
@@ -3404,15 +3609,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
3404
3609
  }
3405
3610
 
3406
3611
  // src/Rail.tsx
3407
- import { jsx as jsx53 } from "react/jsx-runtime";
3612
+ import { jsx as jsx54 } from "react/jsx-runtime";
3408
3613
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
3409
- return /* @__PURE__ */ jsx53("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
3614
+ 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 });
3410
3615
  }
3411
3616
 
3412
3617
  // src/RailItem.tsx
3413
- import { jsx as jsx54, jsxs as jsxs36 } from "react/jsx-runtime";
3618
+ import { jsx as jsx55, jsxs as jsxs37 } from "react/jsx-runtime";
3414
3619
  function RailItem({ href, icon, label, active = false, className, ...props }) {
3415
- return /* @__PURE__ */ jsxs36(
3620
+ return /* @__PURE__ */ jsxs37(
3416
3621
  "a",
3417
3622
  {
3418
3623
  href,
@@ -3420,14 +3625,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
3420
3625
  className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
3421
3626
  ...props,
3422
3627
  children: [
3423
- /* @__PURE__ */ jsx54(
3628
+ /* @__PURE__ */ jsx55(
3424
3629
  "div",
3425
3630
  {
3426
3631
  className: cn(
3427
3632
  "flex items-center justify-center rounded-lg p-2 transition-colors",
3428
3633
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
3429
3634
  ),
3430
- children: /* @__PURE__ */ jsx54(
3635
+ children: /* @__PURE__ */ jsx55(
3431
3636
  "span",
3432
3637
  {
3433
3638
  className: cn(
@@ -3439,14 +3644,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
3439
3644
  )
3440
3645
  }
3441
3646
  ),
3442
- /* @__PURE__ */ jsx54("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
3647
+ /* @__PURE__ */ jsx55("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
3443
3648
  ]
3444
3649
  }
3445
3650
  );
3446
3651
  }
3447
3652
 
3448
3653
  // src/Property.tsx
3449
- import { jsx as jsx55, jsxs as jsxs37 } from "react/jsx-runtime";
3654
+ import { jsx as jsx56, jsxs as jsxs38 } from "react/jsx-runtime";
3450
3655
  var VALUE_CLASSES = "contents";
3451
3656
  function Property({ label, layout = "row", children, className }) {
3452
3657
  if (layout === "stacked") {
@@ -3454,25 +3659,25 @@ function Property({ label, layout = "row", children, className }) {
3454
3659
  // gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
3455
3660
  // Peek's topic-details sections already sit at 12px, Ship's rail was
3456
3661
  // 6px, and unifying means the bigger, calmer one.
3457
- /* @__PURE__ */ jsxs37("dl", { className: cn("flex flex-col gap-3", className), children: [
3458
- /* @__PURE__ */ jsx55("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
3459
- /* @__PURE__ */ jsx55("dd", { className: VALUE_CLASSES, children })
3662
+ /* @__PURE__ */ jsxs38("dl", { className: cn("flex flex-col gap-3", className), children: [
3663
+ /* @__PURE__ */ jsx56("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
3664
+ /* @__PURE__ */ jsx56("dd", { className: VALUE_CLASSES, children })
3460
3665
  ] })
3461
3666
  );
3462
3667
  }
3463
- return /* @__PURE__ */ jsxs37("dl", { className: cn("flex items-center gap-2", className), children: [
3464
- /* @__PURE__ */ jsx55("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
3465
- /* @__PURE__ */ jsx55("dd", { className: VALUE_CLASSES, children })
3668
+ return /* @__PURE__ */ jsxs38("dl", { className: cn("flex items-center gap-2", className), children: [
3669
+ /* @__PURE__ */ jsx56("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
3670
+ /* @__PURE__ */ jsx56("dd", { className: VALUE_CLASSES, children })
3466
3671
  ] });
3467
3672
  }
3468
3673
 
3469
3674
  // src/Reaction.tsx
3470
3675
  import { Toggle } from "@base-ui/react/toggle";
3471
- import { jsx as jsx56, jsxs as jsxs38 } from "react/jsx-runtime";
3676
+ import { jsx as jsx57, jsxs as jsxs39 } from "react/jsx-runtime";
3472
3677
  function Reaction({ emoji, count, pressed = false, className, ...props }) {
3473
3678
  return (
3474
3679
  // @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
3475
- /* @__PURE__ */ jsxs38(
3680
+ /* @__PURE__ */ jsxs39(
3476
3681
  Toggle,
3477
3682
  {
3478
3683
  pressed,
@@ -3494,8 +3699,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
3494
3699
  ),
3495
3700
  ...props,
3496
3701
  children: [
3497
- /* @__PURE__ */ jsx56("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
3498
- /* @__PURE__ */ jsx56("span", { className: CHIP_TEXT_CLASSES, children: count })
3702
+ /* @__PURE__ */ jsx57("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
3703
+ /* @__PURE__ */ jsx57("span", { className: CHIP_TEXT_CLASSES, children: count })
3499
3704
  ]
3500
3705
  }
3501
3706
  )
@@ -3505,9 +3710,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
3505
3710
  // src/SearchInput.tsx
3506
3711
  import "react";
3507
3712
  import { Input as Input3 } from "@base-ui/react/input";
3508
- import { jsx as jsx57, jsxs as jsxs39 } from "react/jsx-runtime";
3713
+ import { jsx as jsx58, jsxs as jsxs40 } from "react/jsx-runtime";
3509
3714
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
3510
- return /* @__PURE__ */ jsxs39(
3715
+ return /* @__PURE__ */ jsxs40(
3511
3716
  "div",
3512
3717
  {
3513
3718
  className: cn(
@@ -3519,7 +3724,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
3519
3724
  className
3520
3725
  ),
3521
3726
  children: [
3522
- /* @__PURE__ */ jsx57(
3727
+ /* @__PURE__ */ jsx58(
3523
3728
  Input3,
3524
3729
  {
3525
3730
  className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
@@ -3527,42 +3732,42 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
3527
3732
  ...props
3528
3733
  }
3529
3734
  ),
3530
- shortcut && /* @__PURE__ */ jsx57(Kbd, { children: shortcut })
3735
+ shortcut && /* @__PURE__ */ jsx58(Kbd, { children: shortcut })
3531
3736
  ]
3532
3737
  }
3533
3738
  );
3534
3739
  }
3535
3740
 
3536
3741
  // src/Panel.tsx
3537
- import { jsx as jsx58, jsxs as jsxs40 } from "react/jsx-runtime";
3742
+ import { jsx as jsx59, jsxs as jsxs41 } from "react/jsx-runtime";
3538
3743
  function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
3539
- return /* @__PURE__ */ jsxs40("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
3540
- /* @__PURE__ */ jsx58(ContainerHeader, { title, chevron, actions }),
3744
+ return /* @__PURE__ */ jsxs41("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
3745
+ /* @__PURE__ */ jsx59(ContainerHeader, { title, chevron, actions }),
3541
3746
  broken ? (
3542
3747
  // The message takes the room the body had and centres itself in it.
3543
- /* @__PURE__ */ jsx58("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
3544
- ) : /* @__PURE__ */ jsx58(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
3545
- !broken && footer && /* @__PURE__ */ jsx58("div", { className: "shrink-0", children: footer })
3748
+ /* @__PURE__ */ jsx59("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
3749
+ ) : /* @__PURE__ */ jsx59(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
3750
+ !broken && footer && /* @__PURE__ */ jsx59("div", { className: "shrink-0", children: footer })
3546
3751
  ] });
3547
3752
  }
3548
3753
  function Panel(props) {
3549
- return /* @__PURE__ */ jsx58(
3754
+ return /* @__PURE__ */ jsx59(
3550
3755
  ErrorBoundary,
3551
3756
  {
3552
3757
  label: "panel",
3553
3758
  frame: (message) => (
3554
3759
  // Only the name comes back with the message: the actions and the footer may be what threw.
3555
- /* @__PURE__ */ jsx58(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
3760
+ /* @__PURE__ */ jsx59(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
3556
3761
  ),
3557
- children: /* @__PURE__ */ jsx58(Frame, { ...props })
3762
+ children: /* @__PURE__ */ jsx59(Frame, { ...props })
3558
3763
  }
3559
3764
  );
3560
3765
  }
3561
3766
 
3562
3767
  // src/ListColumn.tsx
3563
- import { jsx as jsx59, jsxs as jsxs41 } from "react/jsx-runtime";
3564
- function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
3565
- return /* @__PURE__ */ jsxs41(
3768
+ import { jsx as jsx60, jsxs as jsxs42 } from "react/jsx-runtime";
3769
+ function Column({ title, chevron = false, titleMenu, actions, above, collapsed = false, children, className, broken = false }) {
3770
+ return /* @__PURE__ */ jsxs42(
3566
3771
  "div",
3567
3772
  {
3568
3773
  className: cn(
@@ -3573,35 +3778,35 @@ function Column({ title, chevron = false, actions, above, collapsed = false, chi
3573
3778
  ),
3574
3779
  "data-collapsed": collapsed || void 0,
3575
3780
  children: [
3576
- /* @__PURE__ */ jsx59(ContainerHeader, { title, chevron, actions }),
3781
+ /* @__PURE__ */ jsx60(ContainerHeader, { title, chevron, titleMenu, actions }),
3577
3782
  above,
3578
3783
  broken ? (
3579
3784
  // The message takes the room the list had and centres itself in it (Katerina, 19 September).
3580
- /* @__PURE__ */ jsx59("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
3581
- ) : /* @__PURE__ */ jsx59(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
3785
+ /* @__PURE__ */ jsx60("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
3786
+ ) : /* @__PURE__ */ jsx60(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
3582
3787
  ]
3583
3788
  }
3584
3789
  );
3585
3790
  }
3586
3791
  function ListColumn(props) {
3587
- return /* @__PURE__ */ jsx59(
3792
+ return /* @__PURE__ */ jsx60(
3588
3793
  ErrorBoundary,
3589
3794
  {
3590
3795
  label: "list panel",
3591
3796
  frame: (message) => (
3592
3797
  // Only the name comes back with the message: the actions and the row above may be what threw.
3593
- /* @__PURE__ */ jsx59(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
3798
+ /* @__PURE__ */ jsx60(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
3594
3799
  ),
3595
- children: /* @__PURE__ */ jsx59(Column, { ...props })
3800
+ children: /* @__PURE__ */ jsx60(Column, { ...props })
3596
3801
  }
3597
3802
  );
3598
3803
  }
3599
3804
 
3600
3805
  // src/Tabs.tsx
3601
3806
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
3602
- import { jsx as jsx60, jsxs as jsxs42 } from "react/jsx-runtime";
3807
+ import { jsx as jsx61, jsxs as jsxs43 } from "react/jsx-runtime";
3603
3808
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
3604
- return /* @__PURE__ */ jsx60(
3809
+ return /* @__PURE__ */ jsx61(
3605
3810
  BaseTabs.Root,
3606
3811
  {
3607
3812
  value: active,
@@ -3609,14 +3814,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
3609
3814
  if (details.reason === "none") onChange(value);
3610
3815
  },
3611
3816
  className,
3612
- children: /* @__PURE__ */ jsx60(
3817
+ children: /* @__PURE__ */ jsx61(
3613
3818
  BaseTabs.List,
3614
3819
  {
3615
3820
  activateOnFocus: true,
3616
3821
  "aria-label": aria["aria-label"],
3617
3822
  "aria-labelledby": aria["aria-labelledby"],
3618
3823
  className: "flex items-center gap-2",
3619
- children: tabs.map((tab) => /* @__PURE__ */ jsxs42(
3824
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs43(
3620
3825
  BaseTabs.Tab,
3621
3826
  {
3622
3827
  value: tab.id,
@@ -3629,9 +3834,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
3629
3834
  ),
3630
3835
  children: [
3631
3836
  tab.icon,
3632
- /* @__PURE__ */ jsxs42("span", { className: "flex items-baseline", children: [
3837
+ /* @__PURE__ */ jsxs43("span", { className: "flex items-baseline", children: [
3633
3838
  tab.label,
3634
- tab.count !== void 0 ? /* @__PURE__ */ jsx60("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
3839
+ tab.count !== void 0 ? /* @__PURE__ */ jsx61("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
3635
3840
  ] })
3636
3841
  ]
3637
3842
  },
@@ -3647,7 +3852,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
3647
3852
  import { createContext as createContext6, useContext as useContext6, useMemo as useMemo5 } from "react";
3648
3853
  import { Toast as BaseToast } from "@base-ui/react/toast";
3649
3854
  import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
3650
- import { jsx as jsx61, jsxs as jsxs43 } from "react/jsx-runtime";
3855
+ import { jsx as jsx62, jsxs as jsxs44 } from "react/jsx-runtime";
3651
3856
  var SURFACE_STYLES = {
3652
3857
  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",
3653
3858
  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",
@@ -3683,16 +3888,16 @@ var pillClassName = (type, hasAction, className) => cn(
3683
3888
  );
3684
3889
  function LeadingIcon({ type }) {
3685
3890
  const Icon = ICONS[type];
3686
- return /* @__PURE__ */ jsx61(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
3891
+ return /* @__PURE__ */ jsx62(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
3687
3892
  }
3688
3893
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
3689
3894
  const hasAction = !!(actionLabel && onAction);
3690
- return /* @__PURE__ */ jsxs43("div", { className: pillClassName(type, hasAction, className), children: [
3691
- /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2 shrink-0", children: [
3692
- leadingIcon && /* @__PURE__ */ jsx61(LeadingIcon, { type }),
3693
- /* @__PURE__ */ jsx61("span", { className: LABEL_CLASSES, children: label })
3895
+ return /* @__PURE__ */ jsxs44("div", { className: pillClassName(type, hasAction, className), children: [
3896
+ /* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 shrink-0", children: [
3897
+ leadingIcon && /* @__PURE__ */ jsx62(LeadingIcon, { type }),
3898
+ /* @__PURE__ */ jsx62("span", { className: LABEL_CLASSES, children: label })
3694
3899
  ] }),
3695
- hasAction && /* @__PURE__ */ jsx61(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
3900
+ hasAction && /* @__PURE__ */ jsx62(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
3696
3901
  ] });
3697
3902
  }
3698
3903
  var ToastContext = createContext6(null);
@@ -3713,9 +3918,9 @@ function ToastProvider({ children }) {
3713
3918
  }),
3714
3919
  [manager]
3715
3920
  );
3716
- return /* @__PURE__ */ jsx61(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs43(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
3921
+ return /* @__PURE__ */ jsx62(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs44(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
3717
3922
  children,
3718
- /* @__PURE__ */ jsx61(BaseToast.Portal, { children: /* @__PURE__ */ jsx61(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx61(ToastList, {}) }) })
3923
+ /* @__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, {}) }) })
3719
3924
  ] }) });
3720
3925
  }
3721
3926
  function ToastList() {
@@ -3723,25 +3928,25 @@ function ToastList() {
3723
3928
  return toasts.map((toast) => {
3724
3929
  const type = toast.type ?? "neutral";
3725
3930
  const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
3726
- return /* @__PURE__ */ jsxs43(
3931
+ return /* @__PURE__ */ jsxs44(
3727
3932
  BaseToast.Root,
3728
3933
  {
3729
3934
  toast,
3730
3935
  swipeDirection: ["left", "down"],
3731
3936
  className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
3732
3937
  children: [
3733
- /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2 shrink-0", children: [
3734
- leadingIcon && /* @__PURE__ */ jsx61(LeadingIcon, { type }),
3735
- /* @__PURE__ */ jsx61(BaseToast.Title, { render: /* @__PURE__ */ jsx61("span", {}), className: LABEL_CLASSES })
3938
+ /* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 shrink-0", children: [
3939
+ leadingIcon && /* @__PURE__ */ jsx62(LeadingIcon, { type }),
3940
+ /* @__PURE__ */ jsx62(BaseToast.Title, { render: /* @__PURE__ */ jsx62("span", {}), className: LABEL_CLASSES })
3736
3941
  ] }),
3737
- actionLabel && /* @__PURE__ */ jsx61(
3942
+ actionLabel && /* @__PURE__ */ jsx62(
3738
3943
  BaseToast.Action,
3739
3944
  {
3740
3945
  onClick: () => {
3741
3946
  onAction?.();
3742
3947
  close(toast.id);
3743
3948
  },
3744
- render: /* @__PURE__ */ jsx61(Button, { variant: "outlined", size: "small", children: actionLabel })
3949
+ render: /* @__PURE__ */ jsx62(Button, { variant: "outlined", size: "small", children: actionLabel })
3745
3950
  }
3746
3951
  )
3747
3952
  ]
@@ -3774,6 +3979,7 @@ export {
3774
3979
  Avatar,
3775
3980
  AvatarGroup,
3776
3981
  Banner,
3982
+ BlockHandle,
3777
3983
  Breadcrumb,
3778
3984
  Button,
3779
3985
  Card,
@@ -3858,6 +4064,7 @@ export {
3858
4064
  TopBar,
3859
4065
  UnreadDot,
3860
4066
  WithTooltip,
4067
+ blockAtY,
3861
4068
  cn,
3862
4069
  hueFor,
3863
4070
  initialsFor,