@estiva-app/ui 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/Breadcrumb.d.ts.map +1 -1
  2. package/dist/CommandPalette.d.ts +121 -0
  3. package/dist/CommandPalette.d.ts.map +1 -0
  4. package/dist/Menu.d.ts +4 -0
  5. package/dist/Menu.d.ts.map +1 -1
  6. package/dist/Toast.d.ts.map +1 -1
  7. package/dist/eslint/has-a-page-and-a-story.d.ts +4 -0
  8. package/dist/eslint/has-a-page-and-a-story.d.ts.map +1 -0
  9. package/dist/eslint/index.d.ts +15 -1
  10. package/dist/eslint/index.d.ts.map +1 -1
  11. package/dist/eslint/index.js +176 -8
  12. package/dist/eslint/index.js.map +3 -3
  13. package/dist/eslint/no-hand-rolled-behaviour.d.ts +3 -0
  14. package/dist/eslint/no-hand-rolled-behaviour.d.ts.map +1 -0
  15. package/dist/eslint/raw-element-outside-a-wrapper.d.ts +29 -0
  16. package/dist/eslint/raw-element-outside-a-wrapper.d.ts.map +1 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +614 -287
  20. package/dist/index.js.map +4 -4
  21. package/package.json +5 -1
  22. package/src/Breadcrumb.tsx +6 -2
  23. package/src/CommandPalette.mdx +139 -0
  24. package/src/CommandPalette.stories.tsx +418 -0
  25. package/src/CommandPalette.test.tsx +415 -0
  26. package/src/CommandPalette.tsx +664 -0
  27. package/src/Menu.tsx +4 -2
  28. package/src/Toast.tsx +12 -24
  29. package/src/eslint/has-a-page-and-a-story.test.ts +57 -0
  30. package/src/eslint/has-a-page-and-a-story.ts +97 -0
  31. package/src/eslint/index.test.ts +35 -3
  32. package/src/eslint/index.ts +58 -13
  33. package/src/eslint/no-hand-rolled-behaviour.test.ts +70 -0
  34. package/src/eslint/no-hand-rolled-behaviour.ts +116 -0
  35. package/src/eslint/raw-element-outside-a-wrapper.test.ts +82 -0
  36. package/src/eslint/raw-element-outside-a-wrapper.ts +85 -0
  37. package/src/index.ts +17 -0
  38. package/stories/Choosing.mdx +1 -0
package/dist/index.js CHANGED
@@ -789,6 +789,20 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
789
789
  ] });
790
790
  }
791
791
 
792
+ // src/CommandPalette.tsx
793
+ import {
794
+ createContext as createContext2,
795
+ useContext as useContext2,
796
+ useEffect,
797
+ useLayoutEffect as useLayoutEffect2,
798
+ useMemo as useMemo2,
799
+ useRef as useRef2,
800
+ useState as useState3
801
+ } from "react";
802
+ import { Dialog } from "@base-ui/react/dialog";
803
+ import { Autocomplete } from "@base-ui/react/autocomplete";
804
+ import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
805
+
792
806
  // src/ChipInput.tsx
793
807
  import { useMemo, useState as useState2 } from "react";
794
808
  import { Button as BaseButton4 } from "@base-ui/react/button";
@@ -1177,8 +1191,381 @@ function ChipInput({
1177
1191
  var GAP3 = 4;
1178
1192
  var VIEWPORT_PAD3 = 8;
1179
1193
 
1194
+ // src/EmptyState.tsx
1195
+ import { IconMessage2 } from "@tabler/icons-react";
1196
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1197
+ function EmptyState({ icon, message, scope = "page", className }) {
1198
+ if (scope === "section") {
1199
+ return /* @__PURE__ */ jsx19("p", { className: cn("text-caption text-text-muted", className), children: message });
1200
+ }
1201
+ return /* @__PURE__ */ jsxs12("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1202
+ /* @__PURE__ */ jsx19("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx19(IconMessage2, { size: 16, stroke: 1.5 }) }),
1203
+ /* @__PURE__ */ jsx19("p", { className: "text-body-2 text-text-secondary text-center", children: message })
1204
+ ] });
1205
+ }
1206
+
1207
+ // src/Field.tsx
1208
+ import { cloneElement, isValidElement } from "react";
1209
+ import { Field as BaseField } from "@base-ui/react/field";
1210
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1211
+ var LINE_STYLES = {
1212
+ helper: "text-caption text-text-muted",
1213
+ warning: "text-caption text-warning-default",
1214
+ error: "text-caption text-error-default"
1215
+ };
1216
+ function Field({ label, required = false, helper, error, children }) {
1217
+ const control = required && isValidElement(children) ? cloneElement(children, {
1218
+ "aria-required": children.props["aria-required"] ?? true
1219
+ }) : children;
1220
+ return /* @__PURE__ */ jsxs13(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
1221
+ /* @__PURE__ */ jsxs13(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1222
+ label,
1223
+ required && /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1224
+ ] }),
1225
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5", children: [
1226
+ control,
1227
+ error != null ? /* @__PURE__ */ jsx20(BaseField.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx20(BaseField.Description, { className: LINE_STYLES.helper, children: helper }) : null
1228
+ ] })
1229
+ ] });
1230
+ }
1231
+ function FieldLine({ tone = "helper", children, className }) {
1232
+ return /* @__PURE__ */ jsx20("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1233
+ }
1234
+
1235
+ // src/Skeleton.tsx
1236
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1237
+ function SkeletonBar({ className, style }) {
1238
+ return /* @__PURE__ */ jsx21("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1239
+ }
1240
+ var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
1241
+ function SkeletonRow({ barWidth = 130 }) {
1242
+ return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1243
+ /* @__PURE__ */ jsx21(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1244
+ /* @__PURE__ */ jsx21(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1245
+ ] });
1246
+ }
1247
+ function SkeletonList({ rows = 8, className }) {
1248
+ return /* @__PURE__ */ jsx21("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx21(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1249
+ }
1250
+
1251
+ // src/CommandPalette.tsx
1252
+ import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1253
+ var PaletteContext = createContext2(null);
1254
+ function usePalette(part) {
1255
+ const palette = useContext2(PaletteContext);
1256
+ if (!palette) throw new Error(`[@estiva-app/ui] ${part} must be inside a CommandPalette.`);
1257
+ return palette;
1258
+ }
1259
+ var CONTROL = 'input:not([type="hidden"]):not([tabindex="-1"]), textarea, button:not([tabindex="-1"]), [role="combobox"]';
1260
+ function firstControl(popup) {
1261
+ if (!popup) return null;
1262
+ const field = popup.querySelector("[data-command-palette-field]");
1263
+ if (field) return field;
1264
+ return popup.querySelector("[data-command-palette-fields]")?.querySelector(CONTROL) ?? null;
1265
+ }
1266
+ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", children }) {
1267
+ const popupRef = useRef2(null);
1268
+ useEffect(() => {
1269
+ if (!open) return;
1270
+ const frame = requestAnimationFrame(() => {
1271
+ const popup = popupRef.current;
1272
+ const active = document.activeElement;
1273
+ if (popup && (!active || active === document.body || active === popup)) firstControl(popup)?.focus();
1274
+ });
1275
+ return () => cancelAnimationFrame(frame);
1276
+ });
1277
+ const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
1278
+ return /* @__PURE__ */ jsx22(Dialog.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs15(Dialog.Portal, { children: [
1279
+ /* @__PURE__ */ jsx22(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1280
+ /* @__PURE__ */ jsx22(Dialog.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx22(
1281
+ Dialog.Popup,
1282
+ {
1283
+ ref: popupRef,
1284
+ "aria-label": label,
1285
+ initialFocus: () => firstControl(popupRef.current) ?? true,
1286
+ onFocus: (e) => {
1287
+ if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
1288
+ },
1289
+ 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",
1290
+ children: /* @__PURE__ */ jsx22(PaletteContext.Provider, { value: context, children })
1291
+ }
1292
+ ) })
1293
+ ] }) });
1294
+ }
1295
+ function LevelChip({ chip, onBack }) {
1296
+ return /* @__PURE__ */ jsx22(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
1297
+ }
1298
+ function useBack(chip, popupRef) {
1299
+ return () => {
1300
+ if (!chip) return;
1301
+ chip.onBack();
1302
+ requestAnimationFrame(() => firstControl(popupRef.current)?.focus());
1303
+ };
1304
+ }
1305
+ function Footer({ keys }) {
1306
+ const { where } = usePalette("The footer");
1307
+ return /* @__PURE__ */ jsxs15("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted", children: [
1308
+ /* @__PURE__ */ jsx22("span", { className: "min-w-0 flex-1 truncate", children: where }),
1309
+ keys.map(([key, word]) => /* @__PURE__ */ jsxs15("span", { className: "flex shrink-0 items-center gap-1.5", children: [
1310
+ /* @__PURE__ */ jsx22(Kbd, { children: key }),
1311
+ " ",
1312
+ word
1313
+ ] }, key))
1314
+ ] });
1315
+ }
1316
+ var lowerFirst = (s) => s.charAt(0).toLowerCase() + s.slice(1);
1317
+ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip, pending, notes = [], empty, children }) {
1318
+ const { modKey, popupRef } = usePalette("CommandPaletteSearch");
1319
+ const back = useBack(chip, popupRef);
1320
+ const items = useMemo2(() => groups.filter((g) => g.rows.length > 0).map((g) => ({ value: g.label, items: g.rows })), [groups]);
1321
+ const rows = items.flatMap((g) => g.items);
1322
+ const [litId, setLitId] = useState3();
1323
+ const lit = litId === void 0 ? void 0 : rows.find((r) => r.id === litId);
1324
+ const inputRef = useRef2(null);
1325
+ const reported = useRef2({});
1326
+ const settled = useRef2(null);
1327
+ const moved = useRef2(false);
1328
+ useLayoutEffect2(() => {
1329
+ const before = settled.current;
1330
+ const now = reported.current;
1331
+ const sameLevel = before?.query === query && before?.level === chip?.label;
1332
+ if (!sameLevel) moved.current = false;
1333
+ if (moved.current && before?.id && now.reason === "none" && now.id !== before.id && sameLevel) {
1334
+ const ids = rows.map((r) => r.id);
1335
+ const want = ids.indexOf(before.id);
1336
+ const at = now.id === void 0 ? -1 : ids.indexOf(now.id);
1337
+ const input = inputRef.current;
1338
+ if (input && want !== -1 && at !== -1) {
1339
+ const key = want > at ? "ArrowDown" : "ArrowUp";
1340
+ for (let step = 0; step < Math.abs(want - at); step++) {
1341
+ input.dispatchEvent(new KeyboardEvent("keydown", { key, bubbles: true, cancelable: true }));
1342
+ }
1343
+ }
1344
+ }
1345
+ settled.current = { id: reported.current.id, query, level: chip?.label };
1346
+ });
1347
+ const onKeyDown = (e) => {
1348
+ if (e.key === "Home" || e.key === "End") {
1349
+ e.preventBaseUIHandler();
1350
+ return;
1351
+ }
1352
+ const field = e.currentTarget;
1353
+ const collapsed = field.selectionStart === field.selectionEnd;
1354
+ const atStart = collapsed && field.selectionStart === 0;
1355
+ const atEnd = collapsed && field.selectionEnd === field.value.length;
1356
+ if (e.key === "Backspace" && (e.ctrlKey || e.metaKey)) {
1357
+ if (lit?.onForget) {
1358
+ e.preventDefault();
1359
+ lit.onForget();
1360
+ }
1361
+ return;
1362
+ }
1363
+ if (e.key === "Backspace" && atStart && chip && !e.shiftKey && !e.altKey) {
1364
+ e.preventDefault();
1365
+ back();
1366
+ return;
1367
+ }
1368
+ if (e.key === "Tab" && !e.shiftKey) {
1369
+ e.preventDefault();
1370
+ lit?.onGoIn?.();
1371
+ return;
1372
+ }
1373
+ if (e.key === "ArrowRight" && atEnd && lit?.onGoIn && !e.shiftKey) {
1374
+ e.preventDefault();
1375
+ lit.onGoIn();
1376
+ }
1377
+ };
1378
+ const keys = [
1379
+ ...rows.length > 1 ? [["\u2191\u2193", "move"]] : [],
1380
+ ...lit ? [lit.onGoIn ? ["Tab", "go in"] : ["Enter", "open"]] : [],
1381
+ ...lit?.onForget ? [[`${modKey}+Backspace`, "forget"]] : [],
1382
+ // Backspace goes back from the start of the field; it is named while the
1383
+ // field is empty, when that is what it will do.
1384
+ ...chip && query === "" ? [["Backspace", "back"]] : [],
1385
+ ["Esc", "close"]
1386
+ ];
1387
+ return /* @__PURE__ */ jsxs15(
1388
+ Autocomplete.Root,
1389
+ {
1390
+ items,
1391
+ mode: "none",
1392
+ inline: true,
1393
+ open: true,
1394
+ value: query,
1395
+ onValueChange: (value, details) => {
1396
+ if (details.reason === "item-press") return;
1397
+ onQueryChange(value);
1398
+ },
1399
+ itemToStringValue: (row) => row.label,
1400
+ autoHighlight: "always",
1401
+ keepHighlight: true,
1402
+ loopFocus: false,
1403
+ onItemHighlighted: (row, details) => {
1404
+ const id = row?.id;
1405
+ reported.current = { id, reason: details.reason };
1406
+ if (details.reason !== "none") moved.current = true;
1407
+ setLitId(id);
1408
+ },
1409
+ children: [
1410
+ /* @__PURE__ */ jsxs15("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1411
+ /* @__PURE__ */ jsx22(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
1412
+ chip && /* @__PURE__ */ jsx22(LevelChip, { chip, onBack: back }),
1413
+ /* @__PURE__ */ jsx22(
1414
+ Autocomplete.Input,
1415
+ {
1416
+ ref: inputRef,
1417
+ "data-command-palette-field": "",
1418
+ placeholder,
1419
+ "aria-label": placeholder,
1420
+ onKeyDown,
1421
+ className: "min-w-0 flex-1 bg-transparent text-input-value text-text-primary outline-none placeholder:text-text-muted"
1422
+ }
1423
+ )
1424
+ ] }),
1425
+ /* @__PURE__ */ jsxs15(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
1426
+ children != null && /* @__PURE__ */ jsx22("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
1427
+ /* @__PURE__ */ jsx22(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs15(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
1428
+ /* @__PURE__ */ jsx22(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx22(SectionLabel, { className: "text-text-secondary", children: group.value }) }),
1429
+ /* @__PURE__ */ jsx22(Autocomplete.Collection, { children: (row) => (
1430
+ /* The menu row, as the list's own option — the way Select
1431
+ puts it on `Select.Item`. One row, two parts. */
1432
+ /* @__PURE__ */ jsx22(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx22(
1433
+ MenuItemBody,
1434
+ {
1435
+ size: "tall",
1436
+ label: row.label,
1437
+ description: row.description,
1438
+ leading: /* @__PURE__ */ jsx22(RowLeading, { row }),
1439
+ submenu: !!row.onGoIn,
1440
+ hint: row.onGoIn ? /* @__PURE__ */ jsx22(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx22(EnterHint, {})
1441
+ }
1442
+ ) }, row.id)
1443
+ ) })
1444
+ ] }, group.value) }),
1445
+ /* @__PURE__ */ jsx22(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs15(Fragment3, { children: [
1446
+ /* @__PURE__ */ jsx22(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
1447
+ /* @__PURE__ */ jsx22("span", { className: "text-caption text-text-muted", children: pending })
1448
+ ] }) }),
1449
+ notes.map((note) => /* @__PURE__ */ jsx22("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx22(FieldLine, { children: note }) }, note)),
1450
+ /* @__PURE__ */ jsx22(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx22(EmptyState, { scope: "section", message: empty }) })
1451
+ ] }),
1452
+ /* @__PURE__ */ jsx22(Footer, { keys })
1453
+ ]
1454
+ }
1455
+ );
1456
+ }
1457
+ function RowLeading({ row }) {
1458
+ if (row.icon != null) {
1459
+ return /* @__PURE__ */ jsx22("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
1460
+ }
1461
+ return /* @__PURE__ */ jsx22("span", { className: "flex size-8 items-center justify-center", children: row.leading });
1462
+ }
1463
+ var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
1464
+ function isTextField(el) {
1465
+ if (el instanceof HTMLTextAreaElement) return true;
1466
+ return el instanceof HTMLInputElement && TEXT_TYPES.has(el.getAttribute("type") ?? "") && el.getAttribute("role") !== "combobox" && el.tabIndex >= 0;
1467
+ }
1468
+ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, working, error, children }) {
1469
+ const { modKey, popupRef } = usePalette("CommandPaletteForm");
1470
+ const back = useBack(chip, popupRef);
1471
+ const frameRef = useRef2(null);
1472
+ const busy = !!working;
1473
+ const busyRef = useRef2(busy);
1474
+ busyRef.current = busy;
1475
+ const returnTo = useRef2(null);
1476
+ const firstInvalid = () => frameRef.current?.querySelector("[data-invalid]")?.querySelector(CONTROL) ?? null;
1477
+ const submit = () => {
1478
+ if (busyRef.current || submitWaits) return;
1479
+ const active = document.activeElement;
1480
+ returnTo.current = active instanceof HTMLElement && frameRef.current?.contains(active) ? active : null;
1481
+ onSubmit();
1482
+ requestAnimationFrame(() => {
1483
+ if (!busyRef.current) firstInvalid()?.focus();
1484
+ });
1485
+ };
1486
+ useLayoutEffect2(() => {
1487
+ if (busy) {
1488
+ frameRef.current?.focus();
1489
+ return;
1490
+ }
1491
+ if (document.activeElement !== frameRef.current) return;
1492
+ const was = returnTo.current;
1493
+ const target = firstInvalid() ?? (was?.isConnected && !was.disabled ? was : null) ?? firstControl(popupRef.current);
1494
+ target?.focus();
1495
+ }, [busy]);
1496
+ const backWorksFrom = (el) => {
1497
+ const frame = frameRef.current;
1498
+ if (!frame || busy || !el || !frame.contains(el)) return false;
1499
+ if (isTextField(el)) return el.value === "";
1500
+ return ![...frame.querySelectorAll("input, textarea")].some(isTextField);
1501
+ };
1502
+ const [backNamed, setBackNamed] = useState3(false);
1503
+ const measure = () => setBackNamed(backWorksFrom(document.activeElement));
1504
+ useLayoutEffect2(measure);
1505
+ const onKeyDown = (e) => {
1506
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
1507
+ e.preventDefault();
1508
+ submit();
1509
+ return;
1510
+ }
1511
+ if (e.key === "Backspace" && !e.ctrlKey && !e.metaKey && !e.altKey && backWorksFrom(e.target)) {
1512
+ e.preventDefault();
1513
+ back();
1514
+ }
1515
+ };
1516
+ const keys = [
1517
+ ...!busy && !submitWaits ? [[`${modKey}+Enter`, lowerFirst(submitLabel)]] : [],
1518
+ ...backNamed ? [["Backspace", "back"]] : [],
1519
+ ["Esc", "close"]
1520
+ ];
1521
+ return /* @__PURE__ */ jsxs15("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
1522
+ /* @__PURE__ */ jsxs15("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
1523
+ icon != null && /* @__PURE__ */ jsx22("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
1524
+ /* @__PURE__ */ jsx22(LevelChip, { chip, onBack: back })
1525
+ ] }),
1526
+ /* @__PURE__ */ jsx22(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx22("fieldset", { "data-command-palette-fields": "", disabled: busy, className: "contents", children: /* @__PURE__ */ jsx22("div", { className: "flex flex-col gap-4", children }) }) }),
1527
+ /* @__PURE__ */ jsxs15("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
1528
+ /* @__PURE__ */ jsx22("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx22(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx22(FieldLine, { tone: "error", children: error }) : null }),
1529
+ /* @__PURE__ */ jsx22(
1530
+ Button,
1531
+ {
1532
+ variant: "primary",
1533
+ onClick: submit,
1534
+ disabled: busy,
1535
+ disabledReason: busy ? void 0 : submitWaits,
1536
+ leadingIcon: busy ? /* @__PURE__ */ jsx22(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
1537
+ children: working ? working.button : submitLabel
1538
+ }
1539
+ )
1540
+ ] }),
1541
+ /* @__PURE__ */ jsx22(Footer, { keys })
1542
+ ] });
1543
+ }
1544
+ var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
1545
+ function CommandPaletteWorking({ children, bars = 2 }) {
1546
+ return /* @__PURE__ */ jsxs15("div", { role: "status", className: "flex flex-col gap-2", children: [
1547
+ /* @__PURE__ */ jsxs15("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
1548
+ /* @__PURE__ */ jsx22(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
1549
+ children
1550
+ ] }),
1551
+ BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx22(SkeletonBar, { className: cn("h-3", width) }, width))
1552
+ ] });
1553
+ }
1554
+ function CommandPaletteAnswer({ children, note }) {
1555
+ const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
1556
+ return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-2", children: [
1557
+ paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx22("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
1558
+ (part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx22("sup", { className: "ml-0.5 font-mono text-small text-accent-primary", children: part.slice(1, -1) }, j) : part
1559
+ ) }, i)),
1560
+ note && /* @__PURE__ */ jsx22(FieldLine, { children: note })
1561
+ ] });
1562
+ }
1563
+ function CommandPaletteQuote({ children }) {
1564
+ return /* @__PURE__ */ jsx22("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
1565
+ }
1566
+
1180
1567
  // src/InlineChip.tsx
1181
- import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1568
+ import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1182
1569
  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";
1183
1570
  var INLINE_CHIP_TONE_CLASSES = {
1184
1571
  /** A thing or a place — anything that is not a person. */
@@ -1200,41 +1587,41 @@ function inlineChipClassName(tone, className) {
1200
1587
  return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
1201
1588
  }
1202
1589
  function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
1203
- const body = /* @__PURE__ */ jsxs12(Fragment3, { children: [
1204
- icon && /* @__PURE__ */ jsx19("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
1590
+ const body = /* @__PURE__ */ jsxs16(Fragment4, { children: [
1591
+ icon && /* @__PURE__ */ jsx23("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
1205
1592
  children
1206
1593
  ] });
1207
1594
  const classes = inlineChipClassName(tone, className);
1208
1595
  if (href === void 0) {
1209
- return /* @__PURE__ */ jsx19("span", { className: classes, ...props, children: body });
1596
+ return /* @__PURE__ */ jsx23("span", { className: classes, ...props, children: body });
1210
1597
  }
1211
- return /* @__PURE__ */ jsx19("a", { href, className: classes, ...props, children: body });
1598
+ return /* @__PURE__ */ jsx23("a", { href, className: classes, ...props, children: body });
1212
1599
  }
1213
1600
 
1214
1601
  // src/IdentityMenu.tsx
1215
- import { useCallback, useRef as useRef2 } from "react";
1602
+ import { useCallback, useRef as useRef3 } from "react";
1216
1603
 
1217
1604
  // src/Divider.tsx
1218
1605
  import { Separator } from "@base-ui/react/separator";
1219
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1606
+ import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1220
1607
  function Divider({ orientation = "horizontal", label, tone = "default", className }) {
1221
1608
  if (label && orientation === "horizontal") {
1222
1609
  const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
1223
- return /* @__PURE__ */ jsxs13(
1610
+ return /* @__PURE__ */ jsxs17(
1224
1611
  Separator,
1225
1612
  {
1226
1613
  orientation: "horizontal",
1227
1614
  "aria-label": label,
1228
1615
  className: cn("flex shrink-0 items-center gap-2 mx-3", className),
1229
1616
  children: [
1230
- /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
1231
- /* @__PURE__ */ jsx20("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
1232
- /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
1617
+ /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
1618
+ /* @__PURE__ */ jsx24("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
1619
+ /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
1233
1620
  ]
1234
1621
  }
1235
1622
  );
1236
1623
  }
1237
- return /* @__PURE__ */ jsx20(
1624
+ return /* @__PURE__ */ jsx24(
1238
1625
  Separator,
1239
1626
  {
1240
1627
  orientation,
@@ -1244,15 +1631,15 @@ function Divider({ orientation = "horizontal", label, tone = "default", classNam
1244
1631
  }
1245
1632
 
1246
1633
  // src/Person.tsx
1247
- import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1634
+ import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1248
1635
  function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
1249
1636
  return (
1250
1637
  // gap-2: the face-to-name distance is one rule (8px) wherever a person
1251
1638
  // appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
1252
1639
  // row agree by construction.
1253
- /* @__PURE__ */ jsxs14("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
1254
- /* @__PURE__ */ jsx21(Avatar, { name, src: picture, size }),
1255
- /* @__PURE__ */ jsx21("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
1640
+ /* @__PURE__ */ jsxs18("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
1641
+ /* @__PURE__ */ jsx25(Avatar, { name, src: picture, size }),
1642
+ /* @__PURE__ */ jsx25("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
1256
1643
  ] })
1257
1644
  );
1258
1645
  }
@@ -1260,10 +1647,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
1260
1647
  // src/PersonTrigger.tsx
1261
1648
  import { Button as BaseButton5 } from "@base-ui/react/button";
1262
1649
  import { IconChevronDown } from "@tabler/icons-react";
1263
- import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1650
+ import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
1264
1651
  function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
1265
1652
  if (compact) {
1266
- return /* @__PURE__ */ jsx22(
1653
+ return /* @__PURE__ */ jsx26(
1267
1654
  BaseButton5,
1268
1655
  {
1269
1656
  type: "button",
@@ -1272,11 +1659,11 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
1272
1659
  "aria-label": props["aria-label"] ?? name ?? fallback,
1273
1660
  className: cn("cursor-pointer rounded-full", className),
1274
1661
  ...props,
1275
- children: /* @__PURE__ */ jsx22(Avatar, { name, src: picture, size: size ?? 36 })
1662
+ children: /* @__PURE__ */ jsx26(Avatar, { name, src: picture, size: size ?? 36 })
1276
1663
  }
1277
1664
  );
1278
1665
  }
1279
- return /* @__PURE__ */ jsxs15(
1666
+ return /* @__PURE__ */ jsxs19(
1280
1667
  BaseButton5,
1281
1668
  {
1282
1669
  type: "button",
@@ -1294,18 +1681,18 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
1294
1681
  ),
1295
1682
  ...props,
1296
1683
  children: [
1297
- /* @__PURE__ */ jsx22(Person, { name, picture, fallback, size: size ?? 22 }),
1298
- /* @__PURE__ */ jsx22(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
1684
+ /* @__PURE__ */ jsx26(Person, { name, picture, fallback, size: size ?? 22 }),
1685
+ /* @__PURE__ */ jsx26(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
1299
1686
  ]
1300
1687
  }
1301
1688
  );
1302
1689
  }
1303
1690
 
1304
1691
  // src/IdentityMenu.tsx
1305
- import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1692
+ import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
1306
1693
  function IdentityPanel({ className, onClose = () => {
1307
1694
  }, ...rest }) {
1308
- return /* @__PURE__ */ jsx23(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx23(IdentityRows, { ...rest, onClose }) });
1695
+ return /* @__PURE__ */ jsx27(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx27(IdentityRows, { ...rest, onClose }) });
1309
1696
  }
1310
1697
  function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
1311
1698
  const act = (action) => () => {
@@ -1313,53 +1700,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
1313
1700
  action();
1314
1701
  };
1315
1702
  const appRows = typeof children === "function" ? children(onClose) : children;
1316
- return /* @__PURE__ */ jsxs16(Fragment4, { children: [
1317
- /* @__PURE__ */ jsxs16(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
1318
- /* @__PURE__ */ jsx23(MenuRow, { children: /* @__PURE__ */ jsx23(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
1319
- /* @__PURE__ */ jsx23(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." }),
1320
- me.email && /* @__PURE__ */ jsxs16(Note, { children: [
1703
+ return /* @__PURE__ */ jsxs20(Fragment5, { children: [
1704
+ /* @__PURE__ */ jsxs20(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
1705
+ /* @__PURE__ */ jsx27(MenuRow, { children: /* @__PURE__ */ jsx27(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
1706
+ /* @__PURE__ */ jsx27(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." }),
1707
+ me.email && /* @__PURE__ */ jsxs20(Note, { children: [
1321
1708
  me.email,
1322
1709
  " \xB7 known to Estiva, never published to the relay"
1323
1710
  ] })
1324
1711
  ] }),
1325
- relayUrl && /* @__PURE__ */ jsxs16(Fragment4, { children: [
1326
- /* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }),
1327
- /* @__PURE__ */ jsxs16(MenuSection, { label: "Workspace", children: [
1328
- /* @__PURE__ */ jsx23(MenuRow, { children: /* @__PURE__ */ jsx23("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
1329
- /* @__PURE__ */ jsx23(Note, { children: "Everyone on this relay shares this workspace, in every app." })
1712
+ relayUrl && /* @__PURE__ */ jsxs20(Fragment5, { children: [
1713
+ /* @__PURE__ */ jsx27(Divider, { className: "mx-0 my-2" }),
1714
+ /* @__PURE__ */ jsxs20(MenuSection, { label: "Workspace", children: [
1715
+ /* @__PURE__ */ jsx27(MenuRow, { children: /* @__PURE__ */ jsx27("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
1716
+ /* @__PURE__ */ jsx27(Note, { children: "Everyone on this relay shares this workspace, in every app." })
1330
1717
  ] })
1331
1718
  ] }),
1332
- appRows && /* @__PURE__ */ jsxs16(Fragment4, { children: [
1333
- /* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }),
1719
+ appRows && /* @__PURE__ */ jsxs20(Fragment5, { children: [
1720
+ /* @__PURE__ */ jsx27(Divider, { className: "mx-0 my-2" }),
1334
1721
  appRows
1335
1722
  ] }),
1336
- signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }) : null,
1337
- signedIn && idBase && /* @__PURE__ */ jsx23(
1723
+ signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx27(Divider, { className: "mx-0 my-2" }) : null,
1724
+ signedIn && idBase && /* @__PURE__ */ jsx27(
1338
1725
  MenuItem,
1339
1726
  {
1340
1727
  label: "Edit your profile in Estiva ID",
1341
1728
  onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
1342
1729
  }
1343
1730
  ),
1344
- onCopyKey && /* @__PURE__ */ jsx23(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
1345
- idBase && onSignOut && /* @__PURE__ */ jsx23(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
1731
+ onCopyKey && /* @__PURE__ */ jsx27(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
1732
+ idBase && onSignOut && /* @__PURE__ */ jsx27(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
1346
1733
  ] });
1347
1734
  }
1348
1735
  function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
1349
- const actions = useRef2(null);
1736
+ const actions = useRef3(null);
1350
1737
  const close = useCallback(() => actions.current?.close(), []);
1351
1738
  return (
1352
1739
  /* The wrapper carries the caller's `className` and nothing else. It used
1353
1740
  to be `relative`, because the panel was positioned against it; the panel
1354
1741
  hangs from the trigger and portals now, so a positioning context here
1355
1742
  would only be a lie about what this box does. */
1356
- /* @__PURE__ */ jsx23("div", { className, children: /* @__PURE__ */ jsx23(
1743
+ /* @__PURE__ */ jsx27("div", { className, children: /* @__PURE__ */ jsx27(
1357
1744
  Menu,
1358
1745
  {
1359
1746
  align: "right",
1360
1747
  actionsRef: actions,
1361
1748
  className: "w-72",
1362
- trigger: /* @__PURE__ */ jsx23(
1749
+ trigger: /* @__PURE__ */ jsx27(
1363
1750
  PersonTrigger,
1364
1751
  {
1365
1752
  name: me.name,
@@ -1370,7 +1757,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
1370
1757
  "aria-label": compact ? "Account menu" : void 0
1371
1758
  }
1372
1759
  ),
1373
- children: /* @__PURE__ */ jsx23(
1760
+ children: /* @__PURE__ */ jsx27(
1374
1761
  IdentityRows,
1375
1762
  {
1376
1763
  me,
@@ -1388,46 +1775,18 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
1388
1775
  );
1389
1776
  }
1390
1777
  function Note({ children }) {
1391
- return /* @__PURE__ */ jsx23("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
1392
- }
1393
-
1394
- // src/Field.tsx
1395
- import { cloneElement, isValidElement } from "react";
1396
- import { Field as BaseField } from "@base-ui/react/field";
1397
- import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1398
- var LINE_STYLES = {
1399
- helper: "text-caption text-text-muted",
1400
- warning: "text-caption text-warning-default",
1401
- error: "text-caption text-error-default"
1402
- };
1403
- function Field({ label, required = false, helper, error, children }) {
1404
- const control = required && isValidElement(children) ? cloneElement(children, {
1405
- "aria-required": children.props["aria-required"] ?? true
1406
- }) : children;
1407
- return /* @__PURE__ */ jsxs17(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
1408
- /* @__PURE__ */ jsxs17(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
1409
- label,
1410
- required && /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
1411
- ] }),
1412
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1.5", children: [
1413
- control,
1414
- error != null ? /* @__PURE__ */ jsx24(BaseField.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx24(BaseField.Description, { className: LINE_STYLES.helper, children: helper }) : null
1415
- ] })
1416
- ] });
1417
- }
1418
- function FieldLine({ tone = "helper", children, className }) {
1419
- return /* @__PURE__ */ jsx24("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1778
+ return /* @__PURE__ */ jsx27("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
1420
1779
  }
1421
1780
 
1422
1781
  // src/Select.tsx
1423
1782
  import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
1424
1783
  import { Select as BaseSelect } from "@base-ui/react/select";
1425
- import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1784
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1426
1785
  var GAP4 = 4;
1427
1786
  var VIEWPORT_PAD4 = 8;
1428
1787
  function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, className, ...aria }) {
1429
1788
  const selected = options.find((o) => o.value === value);
1430
- return /* @__PURE__ */ jsxs18(
1789
+ return /* @__PURE__ */ jsxs21(
1431
1790
  BaseSelect.Root,
1432
1791
  {
1433
1792
  value,
@@ -1435,7 +1794,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1435
1794
  disabled,
1436
1795
  modal: false,
1437
1796
  children: [
1438
- /* @__PURE__ */ jsxs18(
1797
+ /* @__PURE__ */ jsxs21(
1439
1798
  BaseSelect.Trigger,
1440
1799
  {
1441
1800
  "aria-label": ariaLabel,
@@ -1462,20 +1821,20 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1462
1821
  className
1463
1822
  ),
1464
1823
  children: [
1465
- /* @__PURE__ */ jsxs18("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
1466
- selected?.leading && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center", children: selected.leading }),
1467
- /* @__PURE__ */ jsx25(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
1824
+ /* @__PURE__ */ jsxs21("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
1825
+ selected?.leading && /* @__PURE__ */ jsx28("span", { className: "flex shrink-0 items-center", children: selected.leading }),
1826
+ /* @__PURE__ */ jsx28(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
1468
1827
  ] }),
1469
- /* @__PURE__ */ jsx25(
1828
+ /* @__PURE__ */ jsx28(
1470
1829
  BaseSelect.Icon,
1471
1830
  {
1472
- render: /* @__PURE__ */ jsx25(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1831
+ render: /* @__PURE__ */ jsx28(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1473
1832
  }
1474
1833
  )
1475
1834
  ]
1476
1835
  }
1477
1836
  ),
1478
- /* @__PURE__ */ jsx25(BaseSelect.Portal, { children: /* @__PURE__ */ jsx25(
1837
+ /* @__PURE__ */ jsx28(BaseSelect.Portal, { children: /* @__PURE__ */ jsx28(
1479
1838
  BaseSelect.Positioner,
1480
1839
  {
1481
1840
  side: "bottom",
@@ -1484,25 +1843,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1484
1843
  collisionPadding: VIEWPORT_PAD4,
1485
1844
  alignItemWithTrigger: false,
1486
1845
  className: "z-50 data-[anchor-hidden]:hidden",
1487
- children: /* @__PURE__ */ jsx25(
1846
+ children: /* @__PURE__ */ jsx28(
1488
1847
  BaseSelect.Popup,
1489
1848
  {
1490
- render: /* @__PURE__ */ jsx25(MenuPanel, {}),
1849
+ render: /* @__PURE__ */ jsx28(MenuPanel, {}),
1491
1850
  className: "min-w-[var(--anchor-width)] p-0",
1492
- children: /* @__PURE__ */ jsx25(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs18(
1851
+ children: /* @__PURE__ */ jsx28(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs21(
1493
1852
  BaseSelect.Item,
1494
1853
  {
1495
1854
  value: option.value,
1496
1855
  className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
1497
1856
  children: [
1498
- /* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-center gap-2", children: [
1499
- option.leading && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center", children: option.leading }),
1500
- /* @__PURE__ */ jsx25(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
1857
+ /* @__PURE__ */ jsxs21("span", { className: "flex min-w-0 items-center gap-2", children: [
1858
+ option.leading && /* @__PURE__ */ jsx28("span", { className: "flex shrink-0 items-center", children: option.leading }),
1859
+ /* @__PURE__ */ jsx28(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
1501
1860
  ] }),
1502
- /* @__PURE__ */ jsx25(
1861
+ /* @__PURE__ */ jsx28(
1503
1862
  BaseSelect.ItemIndicator,
1504
1863
  {
1505
- render: /* @__PURE__ */ jsx25(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1864
+ render: /* @__PURE__ */ jsx28(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
1506
1865
  }
1507
1866
  )
1508
1867
  ]
@@ -1521,9 +1880,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
1521
1880
  // src/TextInput.tsx
1522
1881
  import { forwardRef } from "react";
1523
1882
  import { Input } from "@base-ui/react/input";
1524
- import { jsx as jsx26 } from "react/jsx-runtime";
1883
+ import { jsx as jsx29 } from "react/jsx-runtime";
1525
1884
  var TextInput = forwardRef(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
1526
- return /* @__PURE__ */ jsx26(
1885
+ return /* @__PURE__ */ jsx29(
1527
1886
  Input,
1528
1887
  {
1529
1888
  ref,
@@ -1547,13 +1906,13 @@ var TextInput = forwardRef(function TextInput2({ className, type = "text", size
1547
1906
  // src/Textarea.tsx
1548
1907
  import { forwardRef as forwardRef2 } from "react";
1549
1908
  import { Field as BaseField2 } from "@base-ui/react/field";
1550
- import { jsx as jsx27 } from "react/jsx-runtime";
1909
+ import { jsx as jsx30 } from "react/jsx-runtime";
1551
1910
  var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
1552
- return /* @__PURE__ */ jsx27(
1911
+ return /* @__PURE__ */ jsx30(
1553
1912
  BaseField2.Control,
1554
1913
  {
1555
1914
  ref,
1556
- render: /* @__PURE__ */ jsx27("textarea", {}),
1915
+ render: /* @__PURE__ */ jsx30("textarea", {}),
1557
1916
  className: cn(
1558
1917
  "bg-bg-inset border border-border-default focus:border-border-focus rounded-lg px-3 py-2",
1559
1918
  "text-input-value text-text-primary placeholder:text-text-muted",
@@ -1568,27 +1927,27 @@ var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
1568
1927
  });
1569
1928
 
1570
1929
  // src/ConfirmDialog.tsx
1571
- import { useState as useState3 } from "react";
1930
+ import { useState as useState4 } from "react";
1572
1931
 
1573
1932
  // src/DialogShell.tsx
1574
- import { useRef as useRef3 } from "react";
1575
- import { Dialog } from "@base-ui/react/dialog";
1933
+ import { useRef as useRef4 } from "react";
1934
+ import { Dialog as Dialog2 } from "@base-ui/react/dialog";
1576
1935
  import { AlertDialog } from "@base-ui/react/alert-dialog";
1577
1936
  import { IconX as IconX4 } from "@tabler/icons-react";
1578
- import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
1937
+ import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
1579
1938
  function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
1580
- const Parts = alert ? AlertDialog : Dialog;
1581
- const popupRef = useRef3(null);
1582
- return /* @__PURE__ */ jsx28(
1939
+ const Parts = alert ? AlertDialog : Dialog2;
1940
+ const popupRef = useRef4(null);
1941
+ return /* @__PURE__ */ jsx31(
1583
1942
  Parts.Root,
1584
1943
  {
1585
1944
  open: true,
1586
1945
  onOpenChange: (open) => {
1587
1946
  if (!open) onClose();
1588
1947
  },
1589
- children: /* @__PURE__ */ jsxs19(Parts.Portal, { children: [
1590
- /* @__PURE__ */ jsx28(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1591
- /* @__PURE__ */ jsx28("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs19(
1948
+ children: /* @__PURE__ */ jsxs22(Parts.Portal, { children: [
1949
+ /* @__PURE__ */ jsx31(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
1950
+ /* @__PURE__ */ jsx31("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs22(
1592
1951
  Parts.Popup,
1593
1952
  {
1594
1953
  ref: popupRef,
@@ -1597,16 +1956,16 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
1597
1956
  className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
1598
1957
  style: { width },
1599
1958
  children: [
1600
- /* @__PURE__ */ jsxs19("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
1601
- headerContent ?? /* @__PURE__ */ jsx28(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx28("span", {}), children: title }),
1602
- /* @__PURE__ */ jsx28(
1959
+ /* @__PURE__ */ jsxs22("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
1960
+ headerContent ?? /* @__PURE__ */ jsx31(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx31("span", {}), children: title }),
1961
+ /* @__PURE__ */ jsx31(
1603
1962
  Parts.Close,
1604
1963
  {
1605
- render: /* @__PURE__ */ jsx28(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx28(IconX4, { size: 16, stroke: 1.5 }) })
1964
+ render: /* @__PURE__ */ jsx31(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx31(IconX4, { size: 16, stroke: 1.5 }) })
1606
1965
  }
1607
1966
  )
1608
1967
  ] }),
1609
- bodyMaxHeight ? /* @__PURE__ */ jsx28(
1968
+ bodyMaxHeight ? /* @__PURE__ */ jsx31(
1610
1969
  ScrollArea,
1611
1970
  {
1612
1971
  className: cn(footer != null && "border-b border-border-subtle"),
@@ -1614,8 +1973,8 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
1614
1973
  contentClassName: cn("pl-5 pr-4 py-4", bodyClassName),
1615
1974
  children
1616
1975
  }
1617
- ) : /* @__PURE__ */ jsx28("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1618
- footer != null && /* @__PURE__ */ jsx28("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
1976
+ ) : /* @__PURE__ */ jsx31("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1977
+ footer != null && /* @__PURE__ */ jsx31("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
1619
1978
  ]
1620
1979
  }
1621
1980
  ) })
@@ -1625,9 +1984,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
1625
1984
  }
1626
1985
 
1627
1986
  // src/ConfirmDialog.tsx
1628
- import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
1987
+ import { Fragment as Fragment6, jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
1629
1988
  function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
1630
- const [busy, setBusy] = useState3(false);
1989
+ const [busy, setBusy] = useState4(false);
1631
1990
  const confirm = async () => {
1632
1991
  setBusy(true);
1633
1992
  try {
@@ -1637,16 +1996,16 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
1637
1996
  setBusy(false);
1638
1997
  }
1639
1998
  };
1640
- return /* @__PURE__ */ jsx29(
1999
+ return /* @__PURE__ */ jsx32(
1641
2000
  DialogShell,
1642
2001
  {
1643
2002
  alert: true,
1644
2003
  title,
1645
2004
  onClose,
1646
2005
  bodyClassName: "flex flex-col gap-3 text-body-2 text-text-primary",
1647
- footer: /* @__PURE__ */ jsxs20(Fragment5, { children: [
1648
- /* @__PURE__ */ jsx29(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
1649
- /* @__PURE__ */ jsx29(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2006
+ footer: /* @__PURE__ */ jsxs23(Fragment6, { children: [
2007
+ /* @__PURE__ */ jsx32(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2008
+ /* @__PURE__ */ jsx32(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
1650
2009
  ] }),
1651
2010
  children
1652
2011
  }
@@ -1654,16 +2013,16 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
1654
2013
  }
1655
2014
 
1656
2015
  // src/EditableText.tsx
1657
- import { useEffect, useRef as useRef4, useState as useState4 } from "react";
2016
+ import { useEffect as useEffect2, useRef as useRef5, useState as useState5 } from "react";
1658
2017
  import { Field as BaseField3 } from "@base-ui/react/field";
1659
2018
  import { Input as Input2 } from "@base-ui/react/input";
1660
- import { jsx as jsx30 } from "react/jsx-runtime";
2019
+ import { jsx as jsx33 } from "react/jsx-runtime";
1661
2020
  function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
1662
- const [editing, setEditing] = useState4(false);
1663
- const [draft, setDraft] = useState4(value);
1664
- const [busy, setBusy] = useState4(false);
1665
- const fieldRef = useRef4(null);
1666
- useEffect(() => {
2021
+ const [editing, setEditing] = useState5(false);
2022
+ const [draft, setDraft] = useState5(value);
2023
+ const [busy, setBusy] = useState5(false);
2024
+ const fieldRef = useRef5(null);
2025
+ useEffect2(() => {
1667
2026
  if (editing) {
1668
2027
  fieldRef.current?.focus();
1669
2028
  fieldRef.current?.select();
@@ -1715,7 +2074,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1715
2074
  written and never read. Read-only, this is a line of text: whatever
1716
2075
  names the region around it (a `Field`, a `Property`) names this too.
1717
2076
  */
1718
- /* @__PURE__ */ jsx30(
2077
+ /* @__PURE__ */ jsx33(
1719
2078
  "div",
1720
2079
  {
1721
2080
  className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
@@ -1725,11 +2084,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1725
2084
  );
1726
2085
  }
1727
2086
  if (editing) {
1728
- return multiline ? /* @__PURE__ */ jsx30(
2087
+ return multiline ? /* @__PURE__ */ jsx33(
1729
2088
  BaseField3.Control,
1730
2089
  {
1731
2090
  ref: fieldRef,
1732
- render: /* @__PURE__ */ jsx30("textarea", { rows: 4 }),
2091
+ render: /* @__PURE__ */ jsx33("textarea", { rows: 4 }),
1733
2092
  "aria-label": label,
1734
2093
  value: draft,
1735
2094
  disabled: busy,
@@ -1738,7 +2097,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1738
2097
  onBlur: () => void commit(),
1739
2098
  className: fieldClass
1740
2099
  }
1741
- ) : /* @__PURE__ */ jsx30(
2100
+ ) : /* @__PURE__ */ jsx33(
1742
2101
  Input2,
1743
2102
  {
1744
2103
  ref: fieldRef,
@@ -1752,7 +2111,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1752
2111
  }
1753
2112
  );
1754
2113
  }
1755
- return /* @__PURE__ */ jsx30(
2114
+ return /* @__PURE__ */ jsx33(
1756
2115
  "button",
1757
2116
  {
1758
2117
  type: "button",
@@ -1769,22 +2128,9 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
1769
2128
  );
1770
2129
  }
1771
2130
 
1772
- // src/EmptyState.tsx
1773
- import { IconMessage2 } from "@tabler/icons-react";
1774
- import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
1775
- function EmptyState({ icon, message, scope = "page", className }) {
1776
- if (scope === "section") {
1777
- return /* @__PURE__ */ jsx31("p", { className: cn("text-caption text-text-muted", className), children: message });
1778
- }
1779
- return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
1780
- /* @__PURE__ */ jsx31("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx31(IconMessage2, { size: 16, stroke: 1.5 }) }),
1781
- /* @__PURE__ */ jsx31("p", { className: "text-body-2 text-text-secondary text-center", children: message })
1782
- ] });
1783
- }
1784
-
1785
2131
  // src/ProgressBar.tsx
1786
2132
  import { Progress } from "@base-ui/react/progress";
1787
- import { jsx as jsx32 } from "react/jsx-runtime";
2133
+ import { jsx as jsx34 } from "react/jsx-runtime";
1788
2134
  var TRACK_CLASSES = {
1789
2135
  default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
1790
2136
  // 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
@@ -1797,33 +2143,17 @@ var INDICATOR_CLASSES = {
1797
2143
  function ProgressBar({ value, max, label, variant = "default", className }) {
1798
2144
  return (
1799
2145
  // `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
1800
- /* @__PURE__ */ jsx32(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx32(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx32(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
2146
+ /* @__PURE__ */ jsx34(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx34(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx34(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
1801
2147
  );
1802
2148
  }
1803
2149
 
1804
- // src/Skeleton.tsx
1805
- import { jsx as jsx33, jsxs as jsxs22 } from "react/jsx-runtime";
1806
- function SkeletonBar({ className, style }) {
1807
- return /* @__PURE__ */ jsx33("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
1808
- }
1809
- var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
1810
- function SkeletonRow({ barWidth = 130 }) {
1811
- return /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
1812
- /* @__PURE__ */ jsx33(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
1813
- /* @__PURE__ */ jsx33(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
1814
- ] });
1815
- }
1816
- function SkeletonList({ rows = 8, className }) {
1817
- return /* @__PURE__ */ jsx33("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx33(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
1818
- }
1819
-
1820
2150
  // src/Breadcrumb.tsx
1821
- import { Fragment as Fragment6, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState5 } from "react";
1822
- import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
2151
+ import { Fragment as Fragment7, useCallback as useCallback2, useLayoutEffect as useLayoutEffect3, useRef as useRef6, useState as useState6 } from "react";
2152
+ import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
1823
2153
  function Breadcrumb({ items, className }) {
1824
- const navRef = useRef5(null);
1825
- const labelRefs = useRef5([]);
1826
- const [truncated, setTruncated] = useState5(/* @__PURE__ */ new Set());
2154
+ const navRef = useRef6(null);
2155
+ const labelRefs = useRef6([]);
2156
+ const [truncated, setTruncated] = useState6(/* @__PURE__ */ new Set());
1827
2157
  const measure = useCallback2(() => {
1828
2158
  const next = /* @__PURE__ */ new Set();
1829
2159
  labelRefs.current.forEach((el, index) => {
@@ -1831,7 +2161,7 @@ function Breadcrumb({ items, className }) {
1831
2161
  });
1832
2162
  setTruncated((prev) => prev.size === next.size && [...next].every((i) => prev.has(i)) ? prev : next);
1833
2163
  }, []);
1834
- useLayoutEffect2(() => {
2164
+ useLayoutEffect3(() => {
1835
2165
  measure();
1836
2166
  const nav = navRef.current;
1837
2167
  if (!nav || typeof ResizeObserver === "undefined") return;
@@ -1839,7 +2169,7 @@ function Breadcrumb({ items, className }) {
1839
2169
  observer.observe(nav);
1840
2170
  return () => observer.disconnect();
1841
2171
  }, [measure, items]);
1842
- return /* @__PURE__ */ jsx34("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) => {
2172
+ return /* @__PURE__ */ jsx35("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) => {
1843
2173
  const last = index === items.length - 1;
1844
2174
  const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
1845
2175
  const text = cn(
@@ -1853,24 +2183,29 @@ function Breadcrumb({ items, className }) {
1853
2183
  const setLabelRef = (el) => {
1854
2184
  labelRefs.current[index] = el;
1855
2185
  };
1856
- const crumb = item.href ? /* @__PURE__ */ jsx34("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx34("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
1857
- return /* @__PURE__ */ jsxs23(Fragment6, { children: [
1858
- index > 0 && /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
1859
- item.icon && /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
2186
+ const crumb = item.href ? (
2187
+ // `plain` adds no look of its own: a crumb keeps the trail's size and
2188
+ // tone, and brightens on hover. The package's own Link, so a trail
2189
+ // follows whatever a link learns to do (UIG-5).
2190
+ /* @__PURE__ */ jsx35(Link, { ref: setLabelRef, variant: "plain", href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label })
2191
+ ) : /* @__PURE__ */ jsx35("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
2192
+ return /* @__PURE__ */ jsxs24(Fragment7, { children: [
2193
+ index > 0 && /* @__PURE__ */ jsx35("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
2194
+ item.icon && /* @__PURE__ */ jsx35("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
1860
2195
  truncated.has(index) ? (
1861
2196
  // `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
1862
2197
  // must keep truncating inside it, or wrapping it would widen the
1863
2198
  // trail and the tooltip would never be needed again.
1864
- /* @__PURE__ */ jsx34(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
2199
+ /* @__PURE__ */ jsx35(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
1865
2200
  ) : crumb
1866
2201
  ] }, `${item.label}-${index}`);
1867
2202
  }) });
1868
2203
  }
1869
2204
 
1870
2205
  // src/NavItem.tsx
1871
- import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
2206
+ import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
1872
2207
  function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
1873
- return /* @__PURE__ */ jsxs24(
2208
+ return /* @__PURE__ */ jsxs25(
1874
2209
  "a",
1875
2210
  {
1876
2211
  href,
@@ -1885,27 +2220,27 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
1885
2220
  ),
1886
2221
  ...props,
1887
2222
  children: [
1888
- icon && /* @__PURE__ */ jsx35("span", { className: "flex shrink-0 items-center", children: icon }),
1889
- /* @__PURE__ */ jsx35("span", { className: "flex-1 truncate", children: label }),
1890
- count ? /* @__PURE__ */ jsx35(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx35("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
2223
+ icon && /* @__PURE__ */ jsx36("span", { className: "flex shrink-0 items-center", children: icon }),
2224
+ /* @__PURE__ */ jsx36("span", { className: "flex-1 truncate", children: label }),
2225
+ count ? /* @__PURE__ */ jsx36(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx36("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
1891
2226
  ]
1892
2227
  }
1893
2228
  );
1894
2229
  }
1895
2230
 
1896
2231
  // src/Popover.tsx
1897
- import { useMemo as useMemo2 } from "react";
2232
+ import { useMemo as useMemo3 } from "react";
1898
2233
  import { Popover as BasePopover } from "@base-ui/react/popover";
1899
- import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
2234
+ import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
1900
2235
  var GAP5 = 4;
1901
2236
  var VIEWPORT_PAD5 = 8;
1902
2237
  function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
1903
- const anchorTarget = useMemo2(() => {
2238
+ const anchorTarget = useMemo3(() => {
1904
2239
  if (!anchor) return void 0;
1905
2240
  if (anchor instanceof Element) return anchor;
1906
2241
  return { getBoundingClientRect: () => anchor };
1907
2242
  }, [anchor]);
1908
- return /* @__PURE__ */ jsxs25(
2243
+ return /* @__PURE__ */ jsxs26(
1909
2244
  BasePopover.Root,
1910
2245
  {
1911
2246
  open,
@@ -1913,8 +2248,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1913
2248
  actionsRef,
1914
2249
  modal: false,
1915
2250
  children: [
1916
- trigger && /* @__PURE__ */ jsx36(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
1917
- /* @__PURE__ */ jsx36(BasePopover.Portal, { children: /* @__PURE__ */ jsx36(
2251
+ trigger && /* @__PURE__ */ jsx37(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
2252
+ /* @__PURE__ */ jsx37(BasePopover.Portal, { children: /* @__PURE__ */ jsx37(
1918
2253
  BasePopover.Positioner,
1919
2254
  {
1920
2255
  anchor: anchorTarget,
@@ -1923,15 +2258,15 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1923
2258
  sideOffset: GAP5,
1924
2259
  collisionPadding: VIEWPORT_PAD5,
1925
2260
  className: "z-50 data-[anchor-hidden]:hidden",
1926
- children: /* @__PURE__ */ jsx36(
2261
+ children: /* @__PURE__ */ jsx37(
1927
2262
  BasePopover.Popup,
1928
2263
  {
1929
2264
  "aria-label": ariaLabel,
1930
2265
  initialFocus: trigger ? void 0 : false,
1931
2266
  finalFocus,
1932
2267
  className: cn("min-w-[180px] outline-none p-0", className),
1933
- render: /* @__PURE__ */ jsx36(MenuPanel, {}),
1934
- children: /* @__PURE__ */ jsx36(
2268
+ render: /* @__PURE__ */ jsx37(MenuPanel, {}),
2269
+ children: /* @__PURE__ */ jsx37(
1935
2270
  ScrollArea,
1936
2271
  {
1937
2272
  viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
@@ -1950,9 +2285,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1950
2285
 
1951
2286
  // src/Toolbar.tsx
1952
2287
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
1953
- import { jsx as jsx37 } from "react/jsx-runtime";
2288
+ import { jsx as jsx38 } from "react/jsx-runtime";
1954
2289
  function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
1955
- const strip = /* @__PURE__ */ jsx37(
2290
+ const strip = /* @__PURE__ */ jsx38(
1956
2291
  BaseToolbar.Root,
1957
2292
  {
1958
2293
  "aria-label": ariaLabel,
@@ -1963,24 +2298,24 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
1963
2298
  }
1964
2299
  );
1965
2300
  if (!surface) return strip;
1966
- return /* @__PURE__ */ jsx37(MenuPanel, { className: "w-fit p-1", children: strip });
2301
+ return /* @__PURE__ */ jsx38(MenuPanel, { className: "w-fit p-1", children: strip });
1967
2302
  }
1968
2303
  function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
1969
- return /* @__PURE__ */ jsx37(
2304
+ return /* @__PURE__ */ jsx38(
1970
2305
  BaseToolbar.Button,
1971
2306
  {
1972
2307
  ref,
1973
2308
  disabled: disabled || !!disabledReason,
1974
2309
  focusableWhenDisabled: true,
1975
- render: /* @__PURE__ */ jsx37(IconButton, { disabled, disabledReason, ...props })
2310
+ render: /* @__PURE__ */ jsx38(IconButton, { disabled, disabledReason, ...props })
1976
2311
  }
1977
2312
  );
1978
2313
  }
1979
2314
  function ToolbarInput({ size, ...props }) {
1980
- return /* @__PURE__ */ jsx37(BaseToolbar.Input, { render: /* @__PURE__ */ jsx37(TextInput, { size }), ...props });
2315
+ return /* @__PURE__ */ jsx38(BaseToolbar.Input, { render: /* @__PURE__ */ jsx38(TextInput, { size }), ...props });
1981
2316
  }
1982
2317
  function ToolbarSeparator({ className }) {
1983
- return /* @__PURE__ */ jsx37(
2318
+ return /* @__PURE__ */ jsx38(
1984
2319
  BaseToolbar.Separator,
1985
2320
  {
1986
2321
  orientation: "vertical",
@@ -1990,9 +2325,9 @@ function ToolbarSeparator({ className }) {
1990
2325
  }
1991
2326
 
1992
2327
  // src/ReactionPicker.tsx
1993
- import { jsx as jsx38 } from "react/jsx-runtime";
2328
+ import { jsx as jsx39 } from "react/jsx-runtime";
1994
2329
  function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
1995
- return /* @__PURE__ */ jsx38(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
2330
+ return /* @__PURE__ */ jsx39(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
1996
2331
  /*
1997
2332
  A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
1998
2333
  would become the toolbar's item and the button inside it would never
@@ -2002,14 +2337,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
2002
2337
  The tooltip names it for a pointer, `aria-label` for everything else,
2003
2338
  and both say the meaning rather than the glyph.
2004
2339
  */
2005
- /* @__PURE__ */ jsx38(
2340
+ /* @__PURE__ */ jsx39(
2006
2341
  ToolbarButton,
2007
2342
  {
2008
2343
  "aria-label": option.label,
2009
2344
  tooltip: option.label,
2010
2345
  onClick: () => onSelect(option.emoji),
2011
2346
  className: "size-7 text-h3 leading-none",
2012
- children: /* @__PURE__ */ jsx38("span", { "aria-hidden": "true", children: option.emoji })
2347
+ children: /* @__PURE__ */ jsx39("span", { "aria-hidden": "true", children: option.emoji })
2013
2348
  },
2014
2349
  option.emoji
2015
2350
  )
@@ -2018,23 +2353,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
2018
2353
 
2019
2354
  // src/PreviewCard.tsx
2020
2355
  import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
2021
- import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
2356
+ import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
2022
2357
  var GAP6 = 12;
2023
2358
  var VIEWPORT_PAD6 = 8;
2024
2359
  var OPEN_DELAY2 = 350;
2025
2360
  var CLOSE_DELAY = 200;
2026
2361
  function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, wrapperClassName }) {
2027
- return /* @__PURE__ */ jsxs26(BasePreviewCard.Root, { children: [
2028
- /* @__PURE__ */ jsx39(
2362
+ return /* @__PURE__ */ jsxs27(BasePreviewCard.Root, { children: [
2363
+ /* @__PURE__ */ jsx40(
2029
2364
  BasePreviewCard.Trigger,
2030
2365
  {
2031
2366
  delay,
2032
2367
  closeDelay,
2033
- render: /* @__PURE__ */ jsx39("span", { className: cn("inline-flex", wrapperClassName) }),
2368
+ render: /* @__PURE__ */ jsx40("span", { className: cn("inline-flex", wrapperClassName) }),
2034
2369
  children
2035
2370
  }
2036
2371
  ),
2037
- /* @__PURE__ */ jsx39(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx39(
2372
+ /* @__PURE__ */ jsx40(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx40(
2038
2373
  BasePreviewCard.Positioner,
2039
2374
  {
2040
2375
  side,
@@ -2042,12 +2377,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
2042
2377
  sideOffset: GAP6,
2043
2378
  collisionPadding: VIEWPORT_PAD6,
2044
2379
  className: "z-50 data-[anchor-hidden]:hidden",
2045
- children: /* @__PURE__ */ jsx39(
2380
+ children: /* @__PURE__ */ jsx40(
2046
2381
  BasePreviewCard.Popup,
2047
2382
  {
2048
2383
  className: cn("w-[360px] p-3 outline-none", className),
2049
- render: /* @__PURE__ */ jsx39(MenuPanel, {}),
2050
- children: /* @__PURE__ */ jsx39(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3 [&>*]:shrink-0", children: content })
2384
+ render: /* @__PURE__ */ jsx40(MenuPanel, {}),
2385
+ children: /* @__PURE__ */ jsx40(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3 [&>*]:shrink-0", children: content })
2051
2386
  }
2052
2387
  )
2053
2388
  }
@@ -2056,15 +2391,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
2056
2391
  }
2057
2392
 
2058
2393
  // src/Rail.tsx
2059
- import { jsx as jsx40 } from "react/jsx-runtime";
2394
+ import { jsx as jsx41 } from "react/jsx-runtime";
2060
2395
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
2061
- return /* @__PURE__ */ jsx40("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
2396
+ return /* @__PURE__ */ jsx41("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
2062
2397
  }
2063
2398
 
2064
2399
  // src/RailItem.tsx
2065
- import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
2400
+ import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
2066
2401
  function RailItem({ href, icon, label, active = false, className, ...props }) {
2067
- return /* @__PURE__ */ jsxs27(
2402
+ return /* @__PURE__ */ jsxs28(
2068
2403
  "a",
2069
2404
  {
2070
2405
  href,
@@ -2072,14 +2407,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
2072
2407
  className: cn("group flex w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
2073
2408
  ...props,
2074
2409
  children: [
2075
- /* @__PURE__ */ jsx41(
2410
+ /* @__PURE__ */ jsx42(
2076
2411
  "div",
2077
2412
  {
2078
2413
  className: cn(
2079
2414
  "flex items-center justify-center rounded-lg p-2 transition-colors",
2080
2415
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
2081
2416
  ),
2082
- children: /* @__PURE__ */ jsx41(
2417
+ children: /* @__PURE__ */ jsx42(
2083
2418
  "span",
2084
2419
  {
2085
2420
  className: cn(
@@ -2091,27 +2426,27 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
2091
2426
  )
2092
2427
  }
2093
2428
  ),
2094
- /* @__PURE__ */ jsx41("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
2429
+ /* @__PURE__ */ jsx42("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
2095
2430
  ]
2096
2431
  }
2097
2432
  );
2098
2433
  }
2099
2434
 
2100
2435
  // src/Sidebar.tsx
2101
- import { jsx as jsx42 } from "react/jsx-runtime";
2436
+ import { jsx as jsx43 } from "react/jsx-runtime";
2102
2437
  function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
2103
- return /* @__PURE__ */ jsx42(
2438
+ return /* @__PURE__ */ jsx43(
2104
2439
  "nav",
2105
2440
  {
2106
2441
  "aria-label": ariaLabel,
2107
2442
  className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
2108
- children: /* @__PURE__ */ jsx42(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
2443
+ children: /* @__PURE__ */ jsx43(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
2109
2444
  }
2110
2445
  );
2111
2446
  }
2112
2447
 
2113
2448
  // src/Property.tsx
2114
- import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
2449
+ import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2115
2450
  var VALUE_CLASSES = "contents";
2116
2451
  function Property({ label, layout = "row", children, className }) {
2117
2452
  if (layout === "stacked") {
@@ -2119,23 +2454,23 @@ function Property({ label, layout = "row", children, className }) {
2119
2454
  // gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
2120
2455
  // Peek's topic-details sections already sit at 12px, Ship's rail was
2121
2456
  // 6px, and unifying means the bigger, calmer one.
2122
- /* @__PURE__ */ jsxs28("dl", { className: cn("flex flex-col gap-3", className), children: [
2123
- /* @__PURE__ */ jsx43("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
2124
- /* @__PURE__ */ jsx43("dd", { className: VALUE_CLASSES, children })
2457
+ /* @__PURE__ */ jsxs29("dl", { className: cn("flex flex-col gap-3", className), children: [
2458
+ /* @__PURE__ */ jsx44("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
2459
+ /* @__PURE__ */ jsx44("dd", { className: VALUE_CLASSES, children })
2125
2460
  ] })
2126
2461
  );
2127
2462
  }
2128
- return /* @__PURE__ */ jsxs28("dl", { className: cn("flex items-center gap-2", className), children: [
2129
- /* @__PURE__ */ jsx43("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
2130
- /* @__PURE__ */ jsx43("dd", { className: VALUE_CLASSES, children })
2463
+ return /* @__PURE__ */ jsxs29("dl", { className: cn("flex items-center gap-2", className), children: [
2464
+ /* @__PURE__ */ jsx44("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
2465
+ /* @__PURE__ */ jsx44("dd", { className: VALUE_CLASSES, children })
2131
2466
  ] });
2132
2467
  }
2133
2468
 
2134
2469
  // src/Reaction.tsx
2135
2470
  import { Toggle } from "@base-ui/react/toggle";
2136
- import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
2471
+ import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
2137
2472
  function Reaction({ emoji, count, pressed = false, className, ...props }) {
2138
- return /* @__PURE__ */ jsxs29(
2473
+ return /* @__PURE__ */ jsxs30(
2139
2474
  Toggle,
2140
2475
  {
2141
2476
  pressed,
@@ -2157,8 +2492,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
2157
2492
  ),
2158
2493
  ...props,
2159
2494
  children: [
2160
- /* @__PURE__ */ jsx44("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
2161
- /* @__PURE__ */ jsx44("span", { className: "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums", children: count })
2495
+ /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
2496
+ /* @__PURE__ */ jsx45("span", { className: "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums", children: count })
2162
2497
  ]
2163
2498
  }
2164
2499
  );
@@ -2167,9 +2502,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
2167
2502
  // src/SearchInput.tsx
2168
2503
  import "react";
2169
2504
  import { Input as Input3 } from "@base-ui/react/input";
2170
- import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
2505
+ import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
2171
2506
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
2172
- return /* @__PURE__ */ jsxs30(
2507
+ return /* @__PURE__ */ jsxs31(
2173
2508
  "div",
2174
2509
  {
2175
2510
  className: cn(
@@ -2179,7 +2514,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
2179
2514
  className
2180
2515
  ),
2181
2516
  children: [
2182
- /* @__PURE__ */ jsx45(
2517
+ /* @__PURE__ */ jsx46(
2183
2518
  Input3,
2184
2519
  {
2185
2520
  className: "flex-1 min-w-0 bg-transparent text-input-value text-text-primary placeholder:text-text-muted outline-none",
@@ -2187,7 +2522,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
2187
2522
  ...props
2188
2523
  }
2189
2524
  ),
2190
- shortcut && /* @__PURE__ */ jsx45(Kbd, { children: shortcut })
2525
+ shortcut && /* @__PURE__ */ jsx46(Kbd, { children: shortcut })
2191
2526
  ]
2192
2527
  }
2193
2528
  );
@@ -2196,17 +2531,17 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
2196
2531
  // src/SectionHeader.tsx
2197
2532
  import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
2198
2533
  import { useRender } from "@base-ui/react/use-render";
2199
- import { Fragment as Fragment7, jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
2534
+ import { Fragment as Fragment8, jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
2200
2535
  function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", render, className }) {
2201
2536
  const titleElement = useRender({
2202
- render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
2537
+ render: render ?? (chevron ? /* @__PURE__ */ jsx47("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx47("span", {})),
2203
2538
  props: {
2204
2539
  // `text-left`: a button centres its text. `h-full` and `flex-1`: the
2205
2540
  // whole row up to the actions is the hit target, as it was when the
2206
2541
  // row itself carried the click.
2207
2542
  className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
2208
- children: /* @__PURE__ */ jsxs31(Fragment7, { children: [
2209
- chevron && /* @__PURE__ */ jsx46(
2543
+ children: /* @__PURE__ */ jsxs32(Fragment8, { children: [
2544
+ chevron && /* @__PURE__ */ jsx47(
2210
2545
  IconChevronRight2,
2211
2546
  {
2212
2547
  size: 12,
@@ -2214,11 +2549,11 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2214
2549
  className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
2215
2550
  }
2216
2551
  ),
2217
- /* @__PURE__ */ jsx46(SectionLabel, { children: title })
2552
+ /* @__PURE__ */ jsx47(SectionLabel, { children: title })
2218
2553
  ] })
2219
2554
  }
2220
2555
  });
2221
- return /* @__PURE__ */ jsxs31(
2556
+ return /* @__PURE__ */ jsxs32(
2222
2557
  "div",
2223
2558
  {
2224
2559
  className: cn(
@@ -2231,15 +2566,15 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2231
2566
  ),
2232
2567
  children: [
2233
2568
  titleElement,
2234
- trailing != null && /* @__PURE__ */ jsx46("div", { className: "flex shrink-0 items-center", children: trailing }),
2235
- actions && actions.length > 0 && /* @__PURE__ */ jsx46(
2569
+ trailing != null && /* @__PURE__ */ jsx47("div", { className: "flex shrink-0 items-center", children: trailing }),
2570
+ actions && actions.length > 0 && /* @__PURE__ */ jsx47(
2236
2571
  "div",
2237
2572
  {
2238
2573
  className: cn(
2239
2574
  "-mr-1 flex shrink-0 items-center gap-1",
2240
2575
  showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
2241
2576
  ),
2242
- children: actions.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
2577
+ children: actions.map((action) => /* @__PURE__ */ jsx47(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
2243
2578
  }
2244
2579
  )
2245
2580
  ]
@@ -2248,9 +2583,9 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
2248
2583
  }
2249
2584
 
2250
2585
  // src/CollapsibleSection.tsx
2251
- import { useState as useState6 } from "react";
2586
+ import { useState as useState7 } from "react";
2252
2587
  import { Collapsible } from "@base-ui/react/collapsible";
2253
- import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
2588
+ import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
2254
2589
  var OPEN = "open";
2255
2590
  var CLOSED = "closed";
2256
2591
  function readStored(key) {
@@ -2270,21 +2605,21 @@ function writeStored(key, open) {
2270
2605
  }
2271
2606
  }
2272
2607
  function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, children, className, contentClassName }) {
2273
- const [openState, setOpenState] = useState6(() => readStored(storageKey) ?? defaultOpen);
2608
+ const [openState, setOpenState] = useState7(() => readStored(storageKey) ?? defaultOpen);
2274
2609
  const open = openProp ?? openState;
2275
2610
  const setOpen = (next) => {
2276
2611
  setOpenState(next);
2277
2612
  writeStored(storageKey, next);
2278
2613
  onOpenChange?.(next);
2279
2614
  };
2280
- return /* @__PURE__ */ jsxs32(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
2281
- /* @__PURE__ */ jsx47(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx47(Collapsible.Trigger, {}) }),
2282
- /* @__PURE__ */ jsx47(
2615
+ return /* @__PURE__ */ jsxs33(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
2616
+ /* @__PURE__ */ jsx48(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx48(Collapsible.Trigger, {}) }),
2617
+ /* @__PURE__ */ jsx48(
2283
2618
  Collapsible.Panel,
2284
2619
  {
2285
2620
  hiddenUntilFound: true,
2286
2621
  className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
2287
- children: /* @__PURE__ */ jsx47("div", { className: cn("flex flex-col", contentClassName), children })
2622
+ children: /* @__PURE__ */ jsx48("div", { className: cn("flex flex-col", contentClassName), children })
2288
2623
  }
2289
2624
  )
2290
2625
  ] });
@@ -2292,9 +2627,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
2292
2627
 
2293
2628
  // src/Tabs.tsx
2294
2629
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
2295
- import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
2630
+ import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
2296
2631
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
2297
- return /* @__PURE__ */ jsx48(
2632
+ return /* @__PURE__ */ jsx49(
2298
2633
  BaseTabs.Root,
2299
2634
  {
2300
2635
  value: active,
@@ -2302,14 +2637,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
2302
2637
  if (details.reason === "none") onChange(value);
2303
2638
  },
2304
2639
  className,
2305
- children: /* @__PURE__ */ jsx48(
2640
+ children: /* @__PURE__ */ jsx49(
2306
2641
  BaseTabs.List,
2307
2642
  {
2308
2643
  activateOnFocus: true,
2309
2644
  "aria-label": aria["aria-label"],
2310
2645
  "aria-labelledby": aria["aria-labelledby"],
2311
2646
  className: "flex items-center gap-2",
2312
- children: tabs.map((tab) => /* @__PURE__ */ jsxs33(
2647
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs34(
2313
2648
  BaseTabs.Tab,
2314
2649
  {
2315
2650
  value: tab.id,
@@ -2322,9 +2657,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
2322
2657
  ),
2323
2658
  children: [
2324
2659
  tab.icon,
2325
- /* @__PURE__ */ jsxs33("span", { className: "flex items-baseline", children: [
2660
+ /* @__PURE__ */ jsxs34("span", { className: "flex items-baseline", children: [
2326
2661
  tab.label,
2327
- tab.count !== void 0 ? /* @__PURE__ */ jsx48("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
2662
+ tab.count !== void 0 ? /* @__PURE__ */ jsx49("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
2328
2663
  ] })
2329
2664
  ]
2330
2665
  },
@@ -2337,10 +2672,10 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
2337
2672
  }
2338
2673
 
2339
2674
  // src/Toast.tsx
2340
- import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3 } from "react";
2675
+ import { createContext as createContext3, useContext as useContext3, useMemo as useMemo4 } from "react";
2341
2676
  import { Toast as BaseToast } from "@base-ui/react/toast";
2342
2677
  import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
2343
- import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
2678
+ import { jsx as jsx50, jsxs as jsxs35 } from "react/jsx-runtime";
2344
2679
  var SURFACE_STYLES = {
2345
2680
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
2346
2681
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
@@ -2365,13 +2700,6 @@ var ICON_STYLES = {
2365
2700
  // approximated here (D16).
2366
2701
  error: "signal:text-error-default"
2367
2702
  };
2368
- var ACTION_BORDER_STYLES = {
2369
- success: "signal:border signal:border-border-default signal:hover:border-border-strong",
2370
- brand: "signal:border signal:border-border-default signal:hover:border-border-strong",
2371
- neutral: "border border-border-default",
2372
- warning: "signal:border signal:border-border-default signal:hover:border-border-strong",
2373
- error: "signal:border signal:border-border-default signal:hover:border-border-strong"
2374
- };
2375
2703
  var LABEL_CLASSES = "text-body-2 text-text-primary whitespace-nowrap";
2376
2704
  var pillClassName = (type, hasAction, className) => cn(
2377
2705
  "inline-flex items-center min-h-[32px] pl-2 py-1 rounded-lg shadow-lg",
@@ -2381,31 +2709,25 @@ var pillClassName = (type, hasAction, className) => cn(
2381
2709
  SURFACE_STYLES[type],
2382
2710
  className
2383
2711
  );
2384
- var actionClassName = (type) => cn(
2385
- "h-6 flex items-center justify-center gap-1 px-1 py-1 rounded-md shrink-0 transition-colors",
2386
- ACTION_BORDER_STYLES[type],
2387
- type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
2388
- );
2389
2712
  function LeadingIcon({ type }) {
2390
2713
  const Icon = ICONS[type];
2391
- return /* @__PURE__ */ jsx49(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
2714
+ return /* @__PURE__ */ jsx50(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
2392
2715
  }
2393
- var ACTION_LABEL_CLASSES = "text-btn-small text-text-primary whitespace-nowrap";
2394
2716
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
2395
2717
  const hasAction = !!(actionLabel && onAction);
2396
- return /* @__PURE__ */ jsxs34("div", { className: pillClassName(type, hasAction, className), children: [
2397
- /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 shrink-0", children: [
2398
- leadingIcon && /* @__PURE__ */ jsx49(LeadingIcon, { type }),
2399
- /* @__PURE__ */ jsx49("span", { className: LABEL_CLASSES, children: label })
2718
+ return /* @__PURE__ */ jsxs35("div", { className: pillClassName(type, hasAction, className), children: [
2719
+ /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2 shrink-0", children: [
2720
+ leadingIcon && /* @__PURE__ */ jsx50(LeadingIcon, { type }),
2721
+ /* @__PURE__ */ jsx50("span", { className: LABEL_CLASSES, children: label })
2400
2722
  ] }),
2401
- hasAction && /* @__PURE__ */ jsx49("button", { type: "button", onClick: onAction, className: actionClassName(type), children: /* @__PURE__ */ jsx49("span", { className: ACTION_LABEL_CLASSES, children: actionLabel }) })
2723
+ hasAction && /* @__PURE__ */ jsx50(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
2402
2724
  ] });
2403
2725
  }
2404
- var ToastContext = createContext2(null);
2726
+ var ToastContext = createContext3(null);
2405
2727
  var VISIBLE_TOASTS = 3;
2406
2728
  function ToastProvider({ children }) {
2407
- const manager = useMemo3(() => BaseToast.createToastManager(), []);
2408
- const value = useMemo3(
2729
+ const manager = useMemo4(() => BaseToast.createToastManager(), []);
2730
+ const value = useMemo4(
2409
2731
  () => ({
2410
2732
  showToast: ({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, durationMs = 5e3 }) => manager.add({
2411
2733
  title: label,
@@ -2419,9 +2741,9 @@ function ToastProvider({ children }) {
2419
2741
  }),
2420
2742
  [manager]
2421
2743
  );
2422
- return /* @__PURE__ */ jsx49(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs34(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
2744
+ return /* @__PURE__ */ jsx50(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs35(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
2423
2745
  children,
2424
- /* @__PURE__ */ jsx49(BaseToast.Portal, { children: /* @__PURE__ */ jsx49(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx49(ToastList, {}) }) })
2746
+ /* @__PURE__ */ jsx50(BaseToast.Portal, { children: /* @__PURE__ */ jsx50(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx50(ToastList, {}) }) })
2425
2747
  ] }) });
2426
2748
  }
2427
2749
  function ToastList() {
@@ -2429,26 +2751,25 @@ function ToastList() {
2429
2751
  return toasts.map((toast) => {
2430
2752
  const type = toast.type ?? "neutral";
2431
2753
  const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
2432
- return /* @__PURE__ */ jsxs34(
2754
+ return /* @__PURE__ */ jsxs35(
2433
2755
  BaseToast.Root,
2434
2756
  {
2435
2757
  toast,
2436
2758
  swipeDirection: ["left", "down"],
2437
2759
  className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
2438
2760
  children: [
2439
- /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 shrink-0", children: [
2440
- leadingIcon && /* @__PURE__ */ jsx49(LeadingIcon, { type }),
2441
- /* @__PURE__ */ jsx49(BaseToast.Title, { render: /* @__PURE__ */ jsx49("span", {}), className: LABEL_CLASSES })
2761
+ /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2 shrink-0", children: [
2762
+ leadingIcon && /* @__PURE__ */ jsx50(LeadingIcon, { type }),
2763
+ /* @__PURE__ */ jsx50(BaseToast.Title, { render: /* @__PURE__ */ jsx50("span", {}), className: LABEL_CLASSES })
2442
2764
  ] }),
2443
- actionLabel && /* @__PURE__ */ jsx49(
2765
+ actionLabel && /* @__PURE__ */ jsx50(
2444
2766
  BaseToast.Action,
2445
2767
  {
2446
2768
  onClick: () => {
2447
2769
  onAction?.();
2448
2770
  close(toast.id);
2449
2771
  },
2450
- className: actionClassName(type),
2451
- children: /* @__PURE__ */ jsx49("span", { className: ACTION_LABEL_CLASSES, children: actionLabel })
2772
+ render: /* @__PURE__ */ jsx50(Button, { variant: "outlined", size: "small", children: actionLabel })
2452
2773
  }
2453
2774
  )
2454
2775
  ]
@@ -2458,7 +2779,7 @@ function ToastList() {
2458
2779
  });
2459
2780
  }
2460
2781
  function useToast() {
2461
- const ctx = useContext2(ToastContext);
2782
+ const ctx = useContext3(ToastContext);
2462
2783
  if (!ctx) throw new Error("useToast must be used within ToastProvider");
2463
2784
  return ctx;
2464
2785
  }
@@ -2475,6 +2796,12 @@ export {
2475
2796
  Chip,
2476
2797
  ChipInput,
2477
2798
  CollapsibleSection,
2799
+ CommandPalette,
2800
+ CommandPaletteAnswer,
2801
+ CommandPaletteForm,
2802
+ CommandPaletteQuote,
2803
+ CommandPaletteSearch,
2804
+ CommandPaletteWorking,
2478
2805
  ConfirmDialog,
2479
2806
  DialogShell,
2480
2807
  Divider,