@estiva-app/ui 0.58.0 → 0.59.0

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