@estiva-app/ui 0.62.1 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/CodeBlockColours.d.ts +11 -0
  2. package/dist/CodeBlockColours.d.ts.map +1 -0
  3. package/dist/ComposerTriggers.d.ts +8 -2
  4. package/dist/ComposerTriggers.d.ts.map +1 -1
  5. package/dist/KindIcon.d.ts +30 -0
  6. package/dist/KindIcon.d.ts.map +1 -0
  7. package/dist/Link.d.ts +1 -1
  8. package/dist/PastedImages.d.ts +33 -0
  9. package/dist/PastedImages.d.ts.map +1 -0
  10. package/dist/RichText.d.ts +2 -1
  11. package/dist/RichText.d.ts.map +1 -1
  12. package/dist/codeColours.d.ts +29 -0
  13. package/dist/codeColours.d.ts.map +1 -0
  14. package/dist/editor.d.ts +2 -0
  15. package/dist/editor.d.ts.map +1 -1
  16. package/dist/editor.js +86 -13
  17. package/dist/editor.js.map +4 -4
  18. package/dist/eslint/index.js +1 -0
  19. package/dist/eslint/index.js.map +2 -2
  20. package/dist/eslint/no-restyled-part.d.ts.map +1 -1
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +291 -237
  24. package/dist/index.js.map +4 -4
  25. package/package.json +8 -2
  26. package/registry.json +179 -16
  27. package/src/CodeBlockColours.mdx +48 -0
  28. package/src/CodeBlockColours.stories.tsx +37 -0
  29. package/src/CodeBlockColours.ts +14 -0
  30. package/src/ComposerTriggers.mdx +6 -4
  31. package/src/ComposerTriggers.test.tsx +30 -0
  32. package/src/ComposerTriggers.tsx +9 -3
  33. package/src/KindIcon.mdx +58 -0
  34. package/src/KindIcon.stories.tsx +64 -0
  35. package/src/KindIcon.tsx +64 -0
  36. package/src/Link.mdx +1 -1
  37. package/src/Link.stories.tsx +1 -1
  38. package/src/Link.test.tsx +2 -2
  39. package/src/Link.tsx +2 -2
  40. package/src/PastedImages.mdx +61 -0
  41. package/src/PastedImages.stories.tsx +53 -0
  42. package/src/PastedImages.test.ts +83 -0
  43. package/src/PastedImages.ts +105 -0
  44. package/src/RichText.stories.tsx +24 -0
  45. package/src/RichText.tsx +31 -17
  46. package/src/codeColours.ts +33 -0
  47. package/src/editor.ts +2 -0
  48. package/src/eslint/no-restyled-part.ts +1 -0
  49. package/src/index.ts +1 -0
  50. package/src/pages.test.ts +5 -1
  51. package/src/registry/registry.test.ts +7 -7
  52. package/stories/Choosing.mdx +3 -0
  53. package/tailwind-preset.js +8 -0
  54. package/tokens.css +50 -0
package/dist/index.js CHANGED
@@ -71,7 +71,7 @@ function cn(...inputs) {
71
71
  import { jsx as jsx2 } from "react/jsx-runtime";
72
72
  var COVER_CLASSES = "after:absolute after:inset-0 after:rounded-md focus-visible:outline-none focus-visible:after:[outline-style:auto]";
73
73
  var VARIANT_CLASSES = {
74
- text: "text-info-default underline underline-offset-2 hover:opacity-80",
74
+ text: "text-text-interactive underline underline-offset-2 hover:opacity-80",
75
75
  quiet: "hover:underline",
76
76
  underlined: "underline underline-offset-2 hover:text-text-primary",
77
77
  plain: ""
@@ -2421,28 +2421,52 @@ function InlineChip({ tone = "neutral", icon, href, className, children, ...prop
2421
2421
  return /* @__PURE__ */ jsx33("a", { href, className: classes, ...props, onClick: inApp, children: body });
2422
2422
  }
2423
2423
 
2424
+ // src/codeColours.ts
2425
+ import { createElement } from "react";
2426
+ import { common, createLowlight } from "lowlight";
2427
+ var lowlight = createLowlight(common);
2428
+ function draw(node, key) {
2429
+ if (node.type === "text") return node.value;
2430
+ return createElement("span", { key, className: node.properties?.className?.join(" ") }, (node.children ?? []).map(draw));
2431
+ }
2432
+ function codeColours(text, language) {
2433
+ if (!language || !lowlight.registered(language)) return text;
2434
+ return lowlight.highlight(language, text).children.map(draw);
2435
+ }
2436
+
2424
2437
  // src/RichText.tsx
2425
2438
  import { Fragment as Fragment8, jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
2426
2439
  var RICH_TEXT_CLASSES = {
2427
- base: "flex flex-col gap-1 break-words text-text-secondary",
2428
- /* A heading binds to what follows it: 12px above (8 and the 4px gap), 8px below (4 and the gap); two headings in a row, 12px apart. Level 3 keeps the text's colour, one step lower. */
2429
- headings: "[&>:is(h1,h2,h3)]:mb-1 [&>:is(h1,h2,h3)]:mt-2 [&>:is(h1,h2,h3):first-child]:mt-0 [&>:is(h1,h2,h3):last-child]:mb-0 [&>:is(h1,h2,h3)+:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2)]:text-text-primary",
2430
- lists: "[&_:is(ul,ol)]:pl-5 [&_li>p]:m-0 [&_li]:break-words [&_li]:marker:text-text-muted [&_ol]:list-decimal [&_ul]:list-disc",
2440
+ /* Blocks 8px apart (Katerina, 9 October; 4 before). A list's own items stay together. */
2441
+ base: "flex flex-col gap-2 break-words text-text-secondary",
2442
+ /* A heading binds to what follows it: 12px above (4 and the 8px gap), 8px below (the gap); two headings in a row, 12px apart. The same as before the gap grew (Katerina, 9 October: headings do not change). Level 3 keeps the text's colour, one step lower: at the same size as level 2, colour is what tells them apart (Katerina, 9 October). */
2443
+ headings: "[&>:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2,h3):first-child]:mt-0 [&>:is(h1,h2)]:text-text-primary",
2444
+ /* Bullets and numbers in the text's own colour, so a number can be read (Katerina, 9 October; they were the muted grey, 2.4 : 1 in Leaf). */
2445
+ lists: "[&_:is(ul,ol)]:pl-5 [&_li>p]:m-0 [&_li]:break-words [&_li]:marker:text-text-secondary [&_ol]:list-decimal [&_ul]:list-disc",
2446
+ /* The line in the muted text grey, not the border grey: a border grey was 1.3 : 1 in Leaf (Katerina, 9 October). */
2431
2447
  // eslint-disable-next-line token-spacing/no-restricted-classes -- @estiva-escape: the quote line is Peek's, 3px, between the ramp's 2 and 4
2432
- quote: "[&_blockquote>p]:m-0 [&_blockquote]:border-l-[3px] [&_blockquote]:border-border-strong [&_blockquote]:pl-2.5",
2433
- // eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.9 of the text around it, so it scales with a heading and with `small`; a named size is fixed
2434
- code: "[&_:not(pre)>code]:rounded-sm [&_:not(pre)>code]:bg-bg-code [&_:not(pre)>code]:px-1 [&_:not(pre)>code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_code]:text-text-primary",
2435
- // eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.9 of the text around it; the code inside the block is the block's own size, not 0.9 of it again
2436
- codeBlock: "[&_pre>code]:text-[1em] [&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:rounded-md [&_pre]:bg-bg-code [&_pre]:p-2 [&_pre]:font-mono [&_pre]:text-[0.9em] [&_pre]:text-text-primary",
2437
- divider: "[&_hr]:border-border-default",
2448
+ quote: "[&_blockquote>p]:m-0 [&_blockquote]:border-l-[3px] [&_blockquote]:border-text-muted [&_blockquote]:pl-2.5",
2449
+ /* Code in a sentence is amber, its own colour (Katerina, 9 October: option I). */
2450
+ // eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.85 of the text around it, so it scales with a heading and with `small`; a named size is fixed
2451
+ code: "[&_:not(pre)>code]:rounded-sm [&_:not(pre)>code]:bg-bg-code [&_:not(pre)>code]:px-1 [&_:not(pre)>code]:py-0.5 [&_:not(pre)>code]:text-text-code [&_code]:font-mono [&_code]:text-[0.85em] [&_code]:text-text-primary",
2452
+ /* 12px either side, 10px above and below, looser lines than the text (Katerina, 9 October; 8px all round before). */
2453
+ // eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.85 of the text around it; the code inside the block is the block's own size, not 0.85 of it again
2454
+ codeBlock: "[&_pre>code]:text-[1em] [&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:rounded-md [&_pre]:bg-bg-code [&_pre]:px-3 [&_pre]:py-2.5 [&_pre]:font-mono [&_pre]:text-[0.85em] [&_pre]:leading-relaxed [&_pre]:text-text-primary",
2455
+ /* Colours inside a code block, by language: the classes `codeColours` gives each word, after highlight.js's own GitHub theme (Katerina, 9 October). */
2456
+ syntax: "[&_:is(.hljs-keyword,.hljs-doctag,.hljs-type,.hljs-template-tag,.hljs-template-variable)]:text-syntax-keyword [&_.hljs-title]:text-syntax-function [&_:is(.hljs-number,.hljs-literal,.hljs-attr,.hljs-attribute,.hljs-meta,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id)]:text-syntax-constant [&_:is(.hljs-string,.hljs-regexp)]:text-syntax-string [&_:is(.hljs-built_in,.hljs-symbol)]:text-syntax-variable [&_.hljs-comment]:text-syntax-comment [&_:is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo)]:text-syntax-tag",
2457
+ /* A divider splits the text in two: 16px either side (Katerina, 9 October; 4 before). */
2458
+ divider: "[&_hr]:my-2 [&_hr]:border-border-default",
2438
2459
  table: "[&_:is(th,td)>p]:m-0 [&_:is(th,td)]:border [&_:is(th,td)]:border-border-default [&_:is(th,td)]:px-2 [&_:is(th,td)]:py-1 [&_:is(th,td)]:text-left [&_:is(th,td)]:align-top [&_table]:w-full [&_table]:border-collapse [&_th]:bg-bg-code [&_th]:font-medium [&_th]:text-text-primary",
2439
- marks: "[&_em]:italic [&_strong]:font-semibold [&_u]:underline [&_u]:underline-offset-2",
2440
- default: "text-body-2 [&>:is(h2,h3)]:text-body-2 [&>:is(h2,h3)]:font-semibold [&>h1]:text-h4",
2441
- small: "text-caption leading-snug [&>:is(h2,h3)]:text-caption [&>:is(h2,h3)]:font-semibold [&>h1]:text-body-2 [&>h1]:font-semibold"
2460
+ /* Bold in the heading colour, not only heavier. An underlined word draws a faint line, so it does not read as a link (Katerina, 9 October). */
2461
+ marks: "[&_em]:italic [&_strong]:font-semibold [&_strong]:text-text-primary [&_u]:underline [&_u]:decoration-text-muted [&_u]:underline-offset-2",
2462
+ /* Lines 1.5 apart (Katerina, 9 October; 1.4 before). */
2463
+ default: "text-body-2 leading-normal [&>:is(h2,h3)]:text-body-2 [&>:is(h2,h3)]:font-semibold [&>h1]:text-h4",
2464
+ /* Blocks 6px apart; a heading keeps its 12px above and 8px below. */
2465
+ small: "gap-1.5 text-caption leading-snug [&>:is(h1,h2,h3)]:mb-0.5 [&>:is(h1,h2,h3)]:mt-1.5 [&>:is(h1,h2,h3)+:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2,h3):last-child]:mb-0 [&>:is(h2,h3)]:text-caption [&>:is(h2,h3)]:font-semibold [&>h1]:text-body-2 [&>h1]:font-semibold"
2442
2466
  };
2443
2467
  function richTextClassName(size = "default", className) {
2444
- const { base, headings, lists, quote, code, codeBlock, divider, table, marks } = RICH_TEXT_CLASSES;
2445
- return cn(base, headings, lists, quote, code, codeBlock, divider, table, marks, RICH_TEXT_CLASSES[size], className);
2468
+ const { base, headings, lists, quote, code, codeBlock, syntax, divider, table, marks } = RICH_TEXT_CLASSES;
2469
+ return cn(base, headings, lists, quote, code, codeBlock, syntax, divider, table, marks, RICH_TEXT_CLASSES[size], className);
2446
2470
  }
2447
2471
  var LINK_SPLIT = /(\[[^[\]\n]+\]\((?:https?:\/\/|mailto:)[^\s)]+\)|https?:\/\/[^\s]+)/g;
2448
2472
  var WRITTEN_LINK = /^\[([^[\]\n]+)\]\(((?:https?:\/\/|mailto:)[^\s)]+)\)$/;
@@ -2469,15 +2493,15 @@ function textWithLinks(text, renderText) {
2469
2493
  return part ? /* @__PURE__ */ jsx34("span", { children: renderText(part) }, i) : null;
2470
2494
  });
2471
2495
  }
2472
- function Runs({ runs, draw }) {
2496
+ function Runs({ runs, draw: draw2 }) {
2473
2497
  return /* @__PURE__ */ jsx34(Fragment8, { children: (runs ?? []).map((run, i) => {
2474
- if (run.reference) return /* @__PURE__ */ jsx34("span", { children: draw.renderReference(run.reference, run) }, i);
2498
+ if (run.reference) return /* @__PURE__ */ jsx34("span", { children: draw2.renderReference(run.reference, run) }, i);
2475
2499
  if (run.marks.includes("code")) {
2476
2500
  return /* @__PURE__ */ jsx34("code", { children: run.text }, i);
2477
2501
  }
2478
2502
  let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs25("span", { children: [
2479
2503
  j > 0 && /* @__PURE__ */ jsx34("br", {}),
2480
- textWithLinks(line, draw.renderText)
2504
+ textWithLinks(line, draw2.renderText)
2481
2505
  ] }, j));
2482
2506
  if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx34("u", { children: node });
2483
2507
  if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx34("em", { children: node });
@@ -2486,7 +2510,7 @@ function Runs({ runs, draw }) {
2486
2510
  }) });
2487
2511
  }
2488
2512
  var named = (block) => block.typeName ?? block.type;
2489
- function Table({ block, draw }) {
2513
+ function Table({ block, draw: draw2 }) {
2490
2514
  const rows = (block.children ?? []).filter((row) => named(row) === "tableRow");
2491
2515
  if (!rows.length) return null;
2492
2516
  const cells = (row) => (row.children ?? []).map((cell, i) => {
@@ -2500,8 +2524,8 @@ function Table({ block, draw }) {
2500
2524
  colSpan: colspan && colspan > 1 ? colspan : void 0,
2501
2525
  rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
2502
2526
  children: [
2503
- (cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx34(Runs, { runs: child.inline, draw }, j)),
2504
- /* @__PURE__ */ jsx34(Runs, { runs: cell.inline, draw })
2527
+ (cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx34(Runs, { runs: child.inline, draw: draw2 }, j)),
2528
+ /* @__PURE__ */ jsx34(Runs, { runs: cell.inline, draw: draw2 })
2505
2529
  ]
2506
2530
  },
2507
2531
  cell.id ?? i
@@ -2514,10 +2538,10 @@ function Table({ block, draw }) {
2514
2538
  /* @__PURE__ */ jsx34("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx34("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
2515
2539
  ] });
2516
2540
  }
2517
- function Block({ block, draw }) {
2518
- const own = draw.renderBlock?.(block);
2541
+ function Block({ block, draw: draw2 }) {
2542
+ const own = draw2.renderBlock?.(block);
2519
2543
  if (own !== void 0) return own;
2520
- const runs = /* @__PURE__ */ jsx34(Runs, { runs: block.inline, draw });
2544
+ const runs = /* @__PURE__ */ jsx34(Runs, { runs: block.inline, draw: draw2 });
2521
2545
  switch (block.type) {
2522
2546
  case "heading": {
2523
2547
  if (block.level === 1) return /* @__PURE__ */ jsx34("h1", { "data-block-id": block.id, children: runs });
@@ -2528,24 +2552,24 @@ function Block({ block, draw }) {
2528
2552
  return /* @__PURE__ */ jsx34("p", { "data-block-id": block.id, children: runs });
2529
2553
  case "bulletList":
2530
2554
  case "orderedList": {
2531
- const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx34("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx34(Runs, { runs: item.inline, draw }) }, item.id ?? i));
2555
+ const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx34("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx34(Runs, { runs: item.inline, draw: draw2 }) }, item.id ?? i));
2532
2556
  return block.type === "bulletList" ? /* @__PURE__ */ jsx34("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx34("ol", { "data-block-id": block.id, start: block.start, children: items });
2533
2557
  }
2534
2558
  case "blockquote":
2535
2559
  return /* @__PURE__ */ jsx34("blockquote", { "data-block-id": block.id, children: runs });
2536
2560
  case "codeBlock":
2537
- return /* @__PURE__ */ jsx34("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx34("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
2561
+ return /* @__PURE__ */ jsx34("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx34("code", { children: codeColours((block.inline ?? []).map((run) => run.text).join(""), block.language) }) });
2538
2562
  case "horizontalRule":
2539
2563
  return /* @__PURE__ */ jsx34("hr", { "data-block-id": block.id });
2540
2564
  case "table": {
2541
- const table = /* @__PURE__ */ jsx34(Table, { block, draw });
2565
+ const table = /* @__PURE__ */ jsx34(Table, { block, draw: draw2 });
2542
2566
  if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
2543
2567
  break;
2544
2568
  }
2545
2569
  }
2546
2570
  return /* @__PURE__ */ jsxs25("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
2547
2571
  runs,
2548
- (block.children ?? []).map((child, i) => /* @__PURE__ */ jsx34(Block, { block: child, draw }, child.id ?? i))
2572
+ (block.children ?? []).map((child, i) => /* @__PURE__ */ jsx34(Block, { block: child, draw: draw2 }, child.id ?? i))
2549
2573
  ] });
2550
2574
  }
2551
2575
  function RichText({
@@ -2556,23 +2580,51 @@ function RichText({
2556
2580
  renderBlock
2557
2581
  }) {
2558
2582
  if (blocks.length === 0) return null;
2559
- const draw = { renderText, renderReference, renderBlock };
2560
- return /* @__PURE__ */ jsx34("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx34(Block, { block, draw }, block.id ?? i)) });
2583
+ const draw2 = { renderText, renderReference, renderBlock };
2584
+ return /* @__PURE__ */ jsx34("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx34(Block, { block, draw: draw2 }, block.id ?? i)) });
2585
+ }
2586
+
2587
+ // src/KindIcon.tsx
2588
+ import { IconBox, IconCircleDashed, IconFile as IconFile2, IconListDetails, IconMessage } from "@tabler/icons-react";
2589
+ import { jsx as jsx35 } from "react/jsx-runtime";
2590
+ var ICONS = {
2591
+ topic: IconCircleDashed,
2592
+ project: IconBox,
2593
+ issue: IconListDetails,
2594
+ file: IconFile2,
2595
+ message: IconMessage
2596
+ };
2597
+ var KIND_MESSAGE = 9;
2598
+ var KIND_CHANNEL = 39e3;
2599
+ var KIND_BARE_FILE = 30840;
2600
+ var KIND_PROJECT = 30850;
2601
+ var KIND_ISSUE = 30851;
2602
+ function thingKindOf(eventKind) {
2603
+ if (eventKind === KIND_MESSAGE) return "message";
2604
+ if (eventKind === KIND_CHANNEL || eventKind === KIND_BARE_FILE) return "topic";
2605
+ if (eventKind === KIND_PROJECT) return "project";
2606
+ if (eventKind === KIND_ISSUE) return "issue";
2607
+ return "file";
2608
+ }
2609
+ var TONE_CLASSES = { secondary: "text-text-secondary", inherit: "" };
2610
+ function KindIcon({ kind, size = 16, tone = "secondary", className }) {
2611
+ const Icon = ICONS[kind];
2612
+ return /* @__PURE__ */ jsx35(Icon, { size, stroke: 1.5, className: cn("shrink-0", TONE_CLASSES[tone], className), "aria-hidden": true });
2561
2613
  }
2562
2614
 
2563
2615
  // src/IdentityMenu.tsx
2564
2616
  import { useCallback as useCallback2, useRef as useRef8 } from "react";
2565
2617
 
2566
2618
  // src/Person.tsx
2567
- import { jsx as jsx35, jsxs as jsxs26 } from "react/jsx-runtime";
2619
+ import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
2568
2620
  function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
2569
2621
  return (
2570
2622
  // gap-2: the face-to-name distance is one rule (8px) wherever a person
2571
2623
  // appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
2572
2624
  // row agree by construction.
2573
2625
  /* @__PURE__ */ jsxs26("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
2574
- /* @__PURE__ */ jsx35(Avatar, { name, src: picture, size }),
2575
- /* @__PURE__ */ jsx35("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
2626
+ /* @__PURE__ */ jsx36(Avatar, { name, src: picture, size }),
2627
+ /* @__PURE__ */ jsx36("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
2576
2628
  ] })
2577
2629
  );
2578
2630
  }
@@ -2580,10 +2632,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
2580
2632
  // src/PersonTrigger.tsx
2581
2633
  import { Button as BaseButton7 } from "@base-ui/react/button";
2582
2634
  import { IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
2583
- import { jsx as jsx36, jsxs as jsxs27 } from "react/jsx-runtime";
2635
+ import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
2584
2636
  function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
2585
2637
  if (compact) {
2586
- return /* @__PURE__ */ jsx36(
2638
+ return /* @__PURE__ */ jsx37(
2587
2639
  BaseButton7,
2588
2640
  {
2589
2641
  type: "button",
@@ -2592,7 +2644,7 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2592
2644
  "aria-label": props["aria-label"] ?? name ?? fallback,
2593
2645
  className: cn("cursor-pointer rounded-full", className),
2594
2646
  ...props,
2595
- children: /* @__PURE__ */ jsx36(Avatar, { name, src: picture, size: size ?? 36 })
2647
+ children: /* @__PURE__ */ jsx37(Avatar, { name, src: picture, size: size ?? 36 })
2596
2648
  }
2597
2649
  );
2598
2650
  }
@@ -2616,8 +2668,8 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2616
2668
  ),
2617
2669
  ...props,
2618
2670
  children: [
2619
- /* @__PURE__ */ jsx36(Person, { name, picture, fallback, size: size ?? 22 }),
2620
- /* @__PURE__ */ jsx36(IconChevronDown2, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
2671
+ /* @__PURE__ */ jsx37(Person, { name, picture, fallback, size: size ?? 22 }),
2672
+ /* @__PURE__ */ jsx37(IconChevronDown2, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
2621
2673
  ]
2622
2674
  }
2623
2675
  )
@@ -2625,10 +2677,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
2625
2677
  }
2626
2678
 
2627
2679
  // src/IdentityMenu.tsx
2628
- import { Fragment as Fragment9, jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
2680
+ import { Fragment as Fragment9, jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
2629
2681
  function IdentityPanel({ className, onClose = () => {
2630
2682
  }, ...rest }) {
2631
- return /* @__PURE__ */ jsx37(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx37(IdentityRows, { ...rest, onClose }) });
2683
+ return /* @__PURE__ */ jsx38(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx38(IdentityRows, { ...rest, onClose }) });
2632
2684
  }
2633
2685
  function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
2634
2686
  const act = (action) => () => {
@@ -2638,34 +2690,34 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
2638
2690
  const appRows = typeof children === "function" ? children(onClose) : children;
2639
2691
  return /* @__PURE__ */ jsxs28(Fragment9, { children: [
2640
2692
  /* @__PURE__ */ jsxs28(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
2641
- /* @__PURE__ */ jsx37(MenuRow, { children: /* @__PURE__ */ jsx37("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx37(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
2642
- /* @__PURE__ */ jsx37(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." }),
2693
+ /* @__PURE__ */ jsx38(MenuRow, { children: /* @__PURE__ */ jsx38("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx38(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
2694
+ /* @__PURE__ */ jsx38(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." }),
2643
2695
  me.email && /* @__PURE__ */ jsxs28(Note, { children: [
2644
2696
  me.email,
2645
2697
  " \xB7 known to Estiva, never published to the relay"
2646
2698
  ] })
2647
2699
  ] }),
2648
2700
  relayUrl && /* @__PURE__ */ jsxs28(Fragment9, { children: [
2649
- /* @__PURE__ */ jsx37(Divider, { className: "mx-0 my-2" }),
2701
+ /* @__PURE__ */ jsx38(Divider, { className: "mx-0 my-2" }),
2650
2702
  /* @__PURE__ */ jsxs28(MenuSection, { label: "Workspace", children: [
2651
- /* @__PURE__ */ jsx37(MenuRow, { children: /* @__PURE__ */ jsx37("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
2652
- /* @__PURE__ */ jsx37(Note, { children: "Everyone on this relay shares this workspace, in every app." })
2703
+ /* @__PURE__ */ jsx38(MenuRow, { children: /* @__PURE__ */ jsx38("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
2704
+ /* @__PURE__ */ jsx38(Note, { children: "Everyone on this relay shares this workspace, in every app." })
2653
2705
  ] })
2654
2706
  ] }),
2655
2707
  appRows && /* @__PURE__ */ jsxs28(Fragment9, { children: [
2656
- /* @__PURE__ */ jsx37(Divider, { className: "mx-0 my-2" }),
2708
+ /* @__PURE__ */ jsx38(Divider, { className: "mx-0 my-2" }),
2657
2709
  appRows
2658
2710
  ] }),
2659
- signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx37(Divider, { className: "mx-0 my-2" }) : null,
2660
- signedIn && idBase && /* @__PURE__ */ jsx37(
2711
+ signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx38(Divider, { className: "mx-0 my-2" }) : null,
2712
+ signedIn && idBase && /* @__PURE__ */ jsx38(
2661
2713
  MenuItem,
2662
2714
  {
2663
2715
  label: "Edit your profile in Estiva ID",
2664
2716
  onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
2665
2717
  }
2666
2718
  ),
2667
- onCopyKey && /* @__PURE__ */ jsx37(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2668
- idBase && onSignOut && /* @__PURE__ */ jsx37(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2719
+ onCopyKey && /* @__PURE__ */ jsx38(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
2720
+ idBase && onSignOut && /* @__PURE__ */ jsx38(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
2669
2721
  ] });
2670
2722
  }
2671
2723
  function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
@@ -2676,13 +2728,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2676
2728
  to be `relative`, because the panel was positioned against it; the panel
2677
2729
  hangs from the trigger and portals now, so a positioning context here
2678
2730
  would only be a lie about what this box does. */
2679
- /* @__PURE__ */ jsx37("div", { className, children: /* @__PURE__ */ jsx37(
2731
+ /* @__PURE__ */ jsx38("div", { className, children: /* @__PURE__ */ jsx38(
2680
2732
  Menu,
2681
2733
  {
2682
2734
  align: "right",
2683
2735
  actionsRef: actions,
2684
2736
  className: "w-72",
2685
- trigger: /* @__PURE__ */ jsx37(
2737
+ trigger: /* @__PURE__ */ jsx38(
2686
2738
  PersonTrigger,
2687
2739
  {
2688
2740
  name: me.name,
@@ -2693,7 +2745,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2693
2745
  "aria-label": compact ? "Account menu" : void 0
2694
2746
  }
2695
2747
  ),
2696
- children: /* @__PURE__ */ jsx37(
2748
+ children: /* @__PURE__ */ jsx38(
2697
2749
  IdentityRows,
2698
2750
  {
2699
2751
  me,
@@ -2711,14 +2763,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
2711
2763
  );
2712
2764
  }
2713
2765
  function Note({ children }) {
2714
- return /* @__PURE__ */ jsx37("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2766
+ return /* @__PURE__ */ jsx38("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
2715
2767
  }
2716
2768
 
2717
2769
  // src/FilePicker.tsx
2718
2770
  import { forwardRef } from "react";
2719
- import { jsx as jsx38 } from "react/jsx-runtime";
2771
+ import { jsx as jsx39 } from "react/jsx-runtime";
2720
2772
  var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
2721
- return /* @__PURE__ */ jsx38(
2773
+ return /* @__PURE__ */ jsx39(
2722
2774
  "input",
2723
2775
  {
2724
2776
  ref,
@@ -2739,7 +2791,7 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
2739
2791
  // src/Select.tsx
2740
2792
  import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
2741
2793
  import { Select as BaseSelect } from "@base-ui/react/select";
2742
- import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
2794
+ import { jsx as jsx40, jsxs as jsxs29 } from "react/jsx-runtime";
2743
2795
  var GAP4 = 4;
2744
2796
  var VIEWPORT_PAD4 = 8;
2745
2797
  function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
@@ -2781,13 +2833,13 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2781
2833
  ),
2782
2834
  children: [
2783
2835
  /* @__PURE__ */ jsxs29("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
2784
- selected?.leading && /* @__PURE__ */ jsx39("span", { className: "flex shrink-0 items-center", children: selected.leading }),
2785
- /* @__PURE__ */ jsx39(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
2836
+ selected?.leading && /* @__PURE__ */ jsx40("span", { className: "flex shrink-0 items-center", children: selected.leading }),
2837
+ /* @__PURE__ */ jsx40(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
2786
2838
  ] }),
2787
- /* @__PURE__ */ jsx39(
2839
+ /* @__PURE__ */ jsx40(
2788
2840
  BaseSelect.Icon,
2789
2841
  {
2790
- render: /* @__PURE__ */ jsx39(IconChevronDown3, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2842
+ render: /* @__PURE__ */ jsx40(IconChevronDown3, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2791
2843
  }
2792
2844
  )
2793
2845
  ]
@@ -2806,8 +2858,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2806
2858
  disabled: disabled && !held,
2807
2859
  modal: false,
2808
2860
  children: [
2809
- held ? /* @__PURE__ */ jsx39(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2810
- /* @__PURE__ */ jsx39(BaseSelect.Portal, { children: /* @__PURE__ */ jsx39(
2861
+ held ? /* @__PURE__ */ jsx40(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
2862
+ /* @__PURE__ */ jsx40(BaseSelect.Portal, { children: /* @__PURE__ */ jsx40(
2811
2863
  BaseSelect.Positioner,
2812
2864
  {
2813
2865
  side: "bottom",
@@ -2816,25 +2868,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2816
2868
  collisionPadding: VIEWPORT_PAD4,
2817
2869
  alignItemWithTrigger: false,
2818
2870
  className: "z-50 data-[anchor-hidden]:hidden",
2819
- children: /* @__PURE__ */ jsx39(
2871
+ children: /* @__PURE__ */ jsx40(
2820
2872
  BaseSelect.Popup,
2821
2873
  {
2822
- render: /* @__PURE__ */ jsx39(MenuPanel, {}),
2874
+ render: /* @__PURE__ */ jsx40(MenuPanel, {}),
2823
2875
  className: "min-w-[var(--anchor-width)] p-0",
2824
- children: /* @__PURE__ */ jsx39(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col gap-0.5 p-2", children: options.map((option) => /* @__PURE__ */ jsxs29(
2876
+ children: /* @__PURE__ */ jsx40(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col gap-0.5 p-2", children: options.map((option) => /* @__PURE__ */ jsxs29(
2825
2877
  BaseSelect.Item,
2826
2878
  {
2827
2879
  value: option.value,
2828
2880
  className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
2829
2881
  children: [
2830
2882
  /* @__PURE__ */ jsxs29("span", { className: "flex min-w-0 items-center gap-2", children: [
2831
- option.leading && /* @__PURE__ */ jsx39("span", { className: "flex shrink-0 items-center", children: option.leading }),
2832
- /* @__PURE__ */ jsx39(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
2883
+ option.leading && /* @__PURE__ */ jsx40("span", { className: "flex shrink-0 items-center", children: option.leading }),
2884
+ /* @__PURE__ */ jsx40(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
2833
2885
  ] }),
2834
- /* @__PURE__ */ jsx39(
2886
+ /* @__PURE__ */ jsx40(
2835
2887
  BaseSelect.ItemIndicator,
2836
2888
  {
2837
- render: /* @__PURE__ */ jsx39(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2889
+ render: /* @__PURE__ */ jsx40(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
2838
2890
  }
2839
2891
  )
2840
2892
  ]
@@ -2853,9 +2905,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2853
2905
  // src/TextInput.tsx
2854
2906
  import { forwardRef as forwardRef2 } from "react";
2855
2907
  import { Input } from "@base-ui/react/input";
2856
- import { jsx as jsx40 } from "react/jsx-runtime";
2908
+ import { jsx as jsx41 } from "react/jsx-runtime";
2857
2909
  var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
2858
- return /* @__PURE__ */ jsx40(
2910
+ return /* @__PURE__ */ jsx41(
2859
2911
  Input,
2860
2912
  {
2861
2913
  ref,
@@ -2881,13 +2933,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
2881
2933
  // src/Textarea.tsx
2882
2934
  import { forwardRef as forwardRef3 } from "react";
2883
2935
  import { Field as BaseField3 } from "@base-ui/react/field";
2884
- import { jsx as jsx41 } from "react/jsx-runtime";
2936
+ import { jsx as jsx42 } from "react/jsx-runtime";
2885
2937
  var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2886
- return /* @__PURE__ */ jsx41(
2938
+ return /* @__PURE__ */ jsx42(
2887
2939
  BaseField3.Control,
2888
2940
  {
2889
2941
  ref,
2890
- render: /* @__PURE__ */ jsx41("textarea", {}),
2942
+ render: /* @__PURE__ */ jsx42("textarea", {}),
2891
2943
  className: cn(
2892
2944
  // The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
2893
2945
  // "aren't there hover states in text input and text area?"). Focus comes after hover in
@@ -2907,7 +2959,7 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
2907
2959
 
2908
2960
  // src/ConfirmDialog.tsx
2909
2961
  import { useState as useState6 } from "react";
2910
- import { Fragment as Fragment10, jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
2962
+ import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
2911
2963
  function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
2912
2964
  const [busy, setBusy] = useState6(false);
2913
2965
  const confirm = async () => {
@@ -2919,17 +2971,17 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
2919
2971
  setBusy(false);
2920
2972
  }
2921
2973
  };
2922
- return /* @__PURE__ */ jsx42(
2974
+ return /* @__PURE__ */ jsx43(
2923
2975
  DialogShell,
2924
2976
  {
2925
2977
  alert: true,
2926
2978
  title,
2927
2979
  onClose,
2928
2980
  footer: /* @__PURE__ */ jsxs30(Fragment10, { children: [
2929
- /* @__PURE__ */ jsx42(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2930
- /* @__PURE__ */ jsx42(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2981
+ /* @__PURE__ */ jsx43(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
2982
+ /* @__PURE__ */ jsx43(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
2931
2983
  ] }),
2932
- children: /* @__PURE__ */ jsx42("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2984
+ children: /* @__PURE__ */ jsx43("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
2933
2985
  }
2934
2986
  );
2935
2987
  }
@@ -2938,7 +2990,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
2938
2990
  import { useEffect as useEffect5, useRef as useRef9, useState as useState7 } from "react";
2939
2991
  import { Field as BaseField4 } from "@base-ui/react/field";
2940
2992
  import { Input as Input2 } from "@base-ui/react/input";
2941
- import { jsx as jsx43 } from "react/jsx-runtime";
2993
+ import { jsx as jsx44 } from "react/jsx-runtime";
2942
2994
  function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
2943
2995
  const [editing, setEditing] = useState7(false);
2944
2996
  const [draft, setDraft] = useState7(value);
@@ -2996,7 +3048,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
2996
3048
  written and never read. Read-only, this is a line of text: whatever
2997
3049
  names the region around it (a `Field`, a `Property`) names this too.
2998
3050
  */
2999
- /* @__PURE__ */ jsx43(
3051
+ /* @__PURE__ */ jsx44(
3000
3052
  "div",
3001
3053
  {
3002
3054
  className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
@@ -3006,11 +3058,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
3006
3058
  );
3007
3059
  }
3008
3060
  if (editing) {
3009
- return multiline ? /* @__PURE__ */ jsx43(
3061
+ return multiline ? /* @__PURE__ */ jsx44(
3010
3062
  BaseField4.Control,
3011
3063
  {
3012
3064
  ref: fieldRef,
3013
- render: /* @__PURE__ */ jsx43("textarea", { rows: 4 }),
3065
+ render: /* @__PURE__ */ jsx44("textarea", { rows: 4 }),
3014
3066
  "aria-label": label,
3015
3067
  value: draft,
3016
3068
  disabled: busy,
@@ -3019,7 +3071,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
3019
3071
  onBlur: () => void commit(),
3020
3072
  className: fieldClass
3021
3073
  }
3022
- ) : /* @__PURE__ */ jsx43(
3074
+ ) : /* @__PURE__ */ jsx44(
3023
3075
  Input2,
3024
3076
  {
3025
3077
  ref: fieldRef,
@@ -3033,7 +3085,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
3033
3085
  }
3034
3086
  );
3035
3087
  }
3036
- return /* @__PURE__ */ jsx43(
3088
+ return /* @__PURE__ */ jsx44(
3037
3089
  "button",
3038
3090
  {
3039
3091
  type: "button",
@@ -3053,7 +3105,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
3053
3105
  // src/ErrorBoundary.tsx
3054
3106
  import { Component } from "react";
3055
3107
  import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
3056
- import { jsx as jsx44 } from "react/jsx-runtime";
3108
+ import { jsx as jsx45 } from "react/jsx-runtime";
3057
3109
  var ErrorBoundary = class extends Component {
3058
3110
  state = { hasError: false };
3059
3111
  static getDerivedStateFromError() {
@@ -3064,22 +3116,22 @@ var ErrorBoundary = class extends Component {
3064
3116
  }
3065
3117
  render() {
3066
3118
  if (!this.state.hasError) return this.props.children;
3067
- const message = /* @__PURE__ */ jsx44(
3119
+ const message = /* @__PURE__ */ jsx45(
3068
3120
  EmptyState,
3069
3121
  {
3070
- icon: /* @__PURE__ */ jsx44(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
3122
+ icon: /* @__PURE__ */ jsx45(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
3071
3123
  message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
3072
3124
  action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
3073
3125
  }
3074
3126
  );
3075
3127
  if (this.props.frame) return this.props.frame(message);
3076
- return this.props.fallbackClassName ? /* @__PURE__ */ jsx44("div", { className: this.props.fallbackClassName, children: message }) : message;
3128
+ return this.props.fallbackClassName ? /* @__PURE__ */ jsx45("div", { className: this.props.fallbackClassName, children: message }) : message;
3077
3129
  }
3078
3130
  };
3079
3131
 
3080
3132
  // src/ProgressBar.tsx
3081
3133
  import { Progress } from "@base-ui/react/progress";
3082
- import { jsx as jsx45 } from "react/jsx-runtime";
3134
+ import { jsx as jsx46 } from "react/jsx-runtime";
3083
3135
  var TRACK_CLASSES = {
3084
3136
  default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
3085
3137
  // 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
@@ -3092,13 +3144,13 @@ var INDICATOR_CLASSES = {
3092
3144
  function ProgressBar({ value, max, label, variant = "default", className }) {
3093
3145
  return (
3094
3146
  // `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
3095
- /* @__PURE__ */ jsx45(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx45(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx45(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
3147
+ /* @__PURE__ */ jsx46(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx46(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx46(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
3096
3148
  );
3097
3149
  }
3098
3150
 
3099
3151
  // src/Breadcrumb.tsx
3100
3152
  import { Fragment as Fragment11, useCallback as useCallback3, useLayoutEffect as useLayoutEffect4, useRef as useRef10, useState as useState8 } from "react";
3101
- import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
3153
+ import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
3102
3154
  function Breadcrumb({ items, className }) {
3103
3155
  const navRef = useRef10(null);
3104
3156
  const labelRefs = useRef10([]);
@@ -3118,7 +3170,7 @@ function Breadcrumb({ items, className }) {
3118
3170
  observer.observe(nav);
3119
3171
  return () => observer.disconnect();
3120
3172
  }, [measure, items]);
3121
- return /* @__PURE__ */ jsx46("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) => {
3173
+ return /* @__PURE__ */ jsx47("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) => {
3122
3174
  const last = index === items.length - 1;
3123
3175
  const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
3124
3176
  const text = cn(
@@ -3139,16 +3191,16 @@ function Breadcrumb({ items, className }) {
3139
3191
  // on a box around it, which the link takes them from, rather than
3140
3192
  // pushed into it (UIG-9); the link is still the one element that
3141
3193
  // truncates and is measured.
3142
- /* @__PURE__ */ jsx46("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx46(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
3143
- ) : /* @__PURE__ */ jsx46("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
3194
+ /* @__PURE__ */ jsx47("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx47(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
3195
+ ) : /* @__PURE__ */ jsx47("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
3144
3196
  return /* @__PURE__ */ jsxs31(Fragment11, { children: [
3145
- index > 0 && /* @__PURE__ */ jsx46("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
3146
- item.icon && /* @__PURE__ */ jsx46("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
3197
+ index > 0 && /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
3198
+ item.icon && /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
3147
3199
  truncated.has(index) ? (
3148
3200
  // `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
3149
3201
  // must keep truncating inside it, or wrapping it would widen the
3150
3202
  // trail and the tooltip would never be needed again.
3151
- /* @__PURE__ */ jsx46(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
3203
+ /* @__PURE__ */ jsx47(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
3152
3204
  ) : crumb
3153
3205
  ] }, `${item.label}-${index}`);
3154
3206
  }) });
@@ -3160,13 +3212,13 @@ import { Collapsible } from "@base-ui/react/collapsible";
3160
3212
  import { IconAlertSquareRounded, IconChevronRight as IconChevronRight2, IconDotsVertical } from "@tabler/icons-react";
3161
3213
 
3162
3214
  // src/UnreadDot.tsx
3163
- import { jsx as jsx47 } from "react/jsx-runtime";
3215
+ import { jsx as jsx48 } from "react/jsx-runtime";
3164
3216
  function UnreadDot({ className }) {
3165
- return /* @__PURE__ */ jsx47("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx47("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
3217
+ return /* @__PURE__ */ jsx48("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx48("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
3166
3218
  }
3167
3219
 
3168
3220
  // src/NavItem.tsx
3169
- import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
3221
+ import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
3170
3222
  function NavItem({
3171
3223
  label,
3172
3224
  href,
@@ -3197,7 +3249,7 @@ function NavItem({
3197
3249
  onOpenChange?.(next);
3198
3250
  };
3199
3251
  const besides = menu != null || hasRows;
3200
- const mark = unread ? urgent ? /* @__PURE__ */ jsx48(UrgentMark, {}) : /* @__PURE__ */ jsx48(UnreadDot, {}) : null;
3252
+ const mark = unread ? urgent ? /* @__PURE__ */ jsx49(UrgentMark, {}) : /* @__PURE__ */ jsx49(UnreadDot, {}) : null;
3201
3253
  const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-has-[:focus-visible]/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0 [@media(hover:none)]:opacity-0";
3202
3254
  const row = /* @__PURE__ */ jsxs32(
3203
3255
  "a",
@@ -3221,7 +3273,7 @@ function NavItem({
3221
3273
  ...props,
3222
3274
  onClick: inApp,
3223
3275
  children: [
3224
- (icon || hasRows) && /* @__PURE__ */ jsx48(
3276
+ (icon || hasRows) && /* @__PURE__ */ jsx49(
3225
3277
  "span",
3226
3278
  {
3227
3279
  className: cn(
@@ -3232,10 +3284,10 @@ function NavItem({
3232
3284
  children: icon
3233
3285
  }
3234
3286
  ),
3235
- /* @__PURE__ */ jsx48("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
3287
+ /* @__PURE__ */ jsx49("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
3236
3288
  hint != null && // Takes room only while it shows, so the label gives way to it.
3237
- /* @__PURE__ */ jsx48("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-has-[:focus-visible]/nav:flex", children: hint }),
3238
- count ? /* @__PURE__ */ jsx48(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx48(
3289
+ /* @__PURE__ */ jsx49("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-has-[:focus-visible]/nav:flex", children: hint }),
3290
+ count ? /* @__PURE__ */ jsx49(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx49(
3239
3291
  "span",
3240
3292
  {
3241
3293
  className: cn(
@@ -3251,7 +3303,7 @@ function NavItem({
3251
3303
  // `-mr-1`: the 24px slot's dot then sits on the axis of a count and
3252
3304
  // of the ⋮ (8px from the edge to the 16px box), one column with a
3253
3305
  // folder heading's dot and ⋮ (Katerina, 5 October).
3254
- /* @__PURE__ */ jsx48("span", { className: cn("-mr-1 flex shrink-0", stepsAside), children: mark })
3306
+ /* @__PURE__ */ jsx49("span", { className: cn("-mr-1 flex shrink-0", stepsAside), children: mark })
3255
3307
  ) : menu != null && !count ? (
3256
3308
  // Nothing at the right, but a menu: no room is kept at rest, so the
3257
3309
  // label has the row's whole width; while the ⋮ shows, its 24px slot
@@ -3259,7 +3311,7 @@ function NavItem({
3259
3311
  // `-mr-1`: the ⋮ sits at `right-1`, 4px into the row's padding, so the
3260
3312
  // slot does too — at the padding's edge it kept 4px the ⋮ never
3261
3313
  // covers, and the label stopped 12px short of the button, not 8.
3262
- /* @__PURE__ */ jsx48("span", { "aria-hidden": "true", className: "-mr-1 hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block [@media(hover:none)]:block" })
3314
+ /* @__PURE__ */ jsx49("span", { "aria-hidden": "true", className: "-mr-1 hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block [@media(hover:none)]:block" })
3263
3315
  ) : null
3264
3316
  ]
3265
3317
  }
@@ -3270,7 +3322,7 @@ function NavItem({
3270
3322
  row,
3271
3323
  hasRows && // `left-1`: the 24px button's 16px arrow then sits where the icon
3272
3324
  // sits (the row's px-2), so the icon turns into the arrow in place.
3273
- /* @__PURE__ */ jsx48("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100", children: /* @__PURE__ */ jsx48(
3325
+ /* @__PURE__ */ jsx49("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100", children: /* @__PURE__ */ jsx49(
3274
3326
  IconButton,
3275
3327
  {
3276
3328
  tooltip: open ? "Collapse" : "Expand",
@@ -3278,7 +3330,7 @@ function NavItem({
3278
3330
  "aria-expanded": open,
3279
3331
  "aria-controls": panelId,
3280
3332
  onClick: () => setOpen(!open),
3281
- children: /* @__PURE__ */ jsx48(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
3333
+ children: /* @__PURE__ */ jsx49(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
3282
3334
  }
3283
3335
  ) }),
3284
3336
  menu != null && // `right-1`: the 24px button's 16px icon ends 8px from the row's
@@ -3289,11 +3341,11 @@ function NavItem({
3289
3341
  // right of the slot's centre.
3290
3342
  // On a screen with no hover it always shows: nothing there can point
3291
3343
  // at the row, and the menu has no other way in.
3292
- /* @__PURE__ */ jsx48("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100"), children: /* @__PURE__ */ jsx48(
3344
+ /* @__PURE__ */ jsx49("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100"), children: /* @__PURE__ */ jsx49(
3293
3345
  Menu,
3294
3346
  {
3295
3347
  align: "right",
3296
- trigger: /* @__PURE__ */ jsx48(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx48(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
3348
+ trigger: /* @__PURE__ */ jsx49(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx49(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
3297
3349
  children: menu
3298
3350
  }
3299
3351
  ) })
@@ -3301,19 +3353,19 @@ function NavItem({
3301
3353
  if (!hasRows) return line;
3302
3354
  return /* @__PURE__ */ jsxs32(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
3303
3355
  line,
3304
- /* @__PURE__ */ jsx48(
3356
+ /* @__PURE__ */ jsx49(
3305
3357
  Collapsible.Panel,
3306
3358
  {
3307
3359
  id: panelId,
3308
3360
  hiddenUntilFound: true,
3309
3361
  className: COLLAPSIBLE_PANEL_CLASSES,
3310
- children: /* @__PURE__ */ jsx48("div", { className: "flex flex-col gap-0.5 pt-0.5 pl-6", children })
3362
+ children: /* @__PURE__ */ jsx49("div", { className: "flex flex-col gap-0.5 pt-0.5 pl-6", children })
3311
3363
  }
3312
3364
  )
3313
3365
  ] });
3314
3366
  }
3315
3367
  function UrgentMark() {
3316
- return /* @__PURE__ */ jsx48("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx48("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx48(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
3368
+ return /* @__PURE__ */ jsx49("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx49("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx49(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
3317
3369
  }
3318
3370
 
3319
3371
  // src/NavTree.tsx
@@ -3326,14 +3378,14 @@ import { Collapsible as Collapsible2 } from "@base-ui/react/collapsible";
3326
3378
  // src/SectionHeader.tsx
3327
3379
  import { IconChevronRight as IconChevronRight3, IconDotsVertical as IconDotsVertical2 } from "@tabler/icons-react";
3328
3380
  import { useRender } from "@base-ui/react/use-render";
3329
- import { Fragment as Fragment12, jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
3381
+ import { Fragment as Fragment12, jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
3330
3382
  function SectionHeader({ title, chevron = false, icon, isExpanded = true, onToggle, trailing, count, actions, menu, menuLabel, showActions = "hover", hover = "fill", look = "heading", render, className }) {
3331
3383
  const row = look === "row";
3332
3384
  const acts = actions && actions.length > 0 || menu != null;
3333
3385
  const trailingClasses = !acts ? "has-[[data-unread]]:-mr-1" : showActions === "hover" && "has-[[data-unread]]:pointer-events-none has-[[data-unread]]:absolute has-[[data-unread]]:inset-y-0 has-[[data-unread]]:right-1 has-[[data-unread]]:w-6 has-[[data-unread]]:justify-center has-[[data-unread]]:transition-opacity group-hover:has-[[data-unread]]:opacity-0 group-has-[:focus-visible]:has-[[data-unread]]:opacity-0 group-has-[[data-section-menu]_[aria-expanded=true]]:has-[[data-unread]]:opacity-0 [@media(hover:none)]:has-[[data-unread]]:opacity-0";
3334
3386
  const reveal = showActions === "hover" && "opacity-0 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100";
3335
3387
  const titleElement = useRender({
3336
- render: render ?? (chevron ? /* @__PURE__ */ jsx49("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx49("span", {})),
3388
+ render: render ?? (chevron ? /* @__PURE__ */ jsx50("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx50("span", {})),
3337
3389
  props: {
3338
3390
  // `text-left`: a button centres its text. `h-full` and `flex-1`: the
3339
3391
  // whole row up to the actions is the hit target, as it was when the
@@ -3342,8 +3394,8 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3342
3394
  className: cn("flex h-full min-w-0 flex-1 items-center text-left", row || chevron || icon != null ? "gap-2" : "gap-1"),
3343
3395
  children: /* @__PURE__ */ jsxs33(Fragment12, { children: [
3344
3396
  icon != null ? /* @__PURE__ */ jsxs33("span", { className: "relative flex size-4 shrink-0 items-center justify-center text-text-secondary", children: [
3345
- /* @__PURE__ */ jsx49("span", { className: cn("flex", chevron && "transition-opacity group-hover:opacity-0 group-has-[:focus-visible]:opacity-0"), children: icon }),
3346
- chevron && /* @__PURE__ */ jsx49(
3397
+ /* @__PURE__ */ jsx50("span", { className: cn("flex", chevron && "transition-opacity group-hover:opacity-0 group-has-[:focus-visible]:opacity-0"), children: icon }),
3398
+ chevron && /* @__PURE__ */ jsx50(
3347
3399
  IconChevronRight3,
3348
3400
  {
3349
3401
  size: 16,
@@ -3351,7 +3403,7 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3351
3403
  className: cn("absolute opacity-0 transition-[opacity,transform] duration-150 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100", isExpanded && "rotate-90")
3352
3404
  }
3353
3405
  )
3354
- ] }) : chevron && /* @__PURE__ */ jsx49(
3406
+ ] }) : chevron && /* @__PURE__ */ jsx50(
3355
3407
  IconChevronRight3,
3356
3408
  {
3357
3409
  size: 16,
@@ -3359,11 +3411,11 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3359
3411
  className: cn("shrink-0 transition-transform duration-150", !row && "text-text-secondary", isExpanded && "rotate-90")
3360
3412
  }
3361
3413
  ),
3362
- look === "quiet" ? /* @__PURE__ */ jsx49("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
3414
+ look === "quiet" ? /* @__PURE__ */ jsx50("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
3363
3415
  // A row's words: NavItem's size and colour, brightening under the pointer with the row.
3364
- /* @__PURE__ */ jsx49("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
3365
- ) : /* @__PURE__ */ jsx49(SectionLabel, { folds: chevron, children: title }),
3366
- count != null && /* @__PURE__ */ jsx49("span", { className: cn("ml-1 shrink-0", COUNT_TEXT_CLASSES), children: count })
3416
+ /* @__PURE__ */ jsx50("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
3417
+ ) : /* @__PURE__ */ jsx50(SectionLabel, { folds: chevron, children: title }),
3418
+ count != null && /* @__PURE__ */ jsx50("span", { className: cn("ml-1 shrink-0", COUNT_TEXT_CLASSES), children: count })
3367
3419
  ] })
3368
3420
  }
3369
3421
  });
@@ -3388,18 +3440,18 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3388
3440
  ),
3389
3441
  children: [
3390
3442
  titleElement,
3391
- trailing != null && /* @__PURE__ */ jsx49("div", { className: cn("flex shrink-0 items-center", trailingClasses), children: trailing }),
3392
- acts && /* @__PURE__ */ jsx49(
3443
+ trailing != null && /* @__PURE__ */ jsx50("div", { className: cn("flex shrink-0 items-center", trailingClasses), children: trailing }),
3444
+ acts && /* @__PURE__ */ jsx50(
3393
3445
  "div",
3394
3446
  {
3395
3447
  className: "-mr-1 flex shrink-0 items-center",
3396
3448
  children: /* @__PURE__ */ jsxs33("div", { className: cn("flex items-center gap-1", reveal), children: [
3397
- actions?.map((action) => /* @__PURE__ */ jsx49(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3398
- menu != null && /* @__PURE__ */ jsx49("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx49(
3449
+ actions?.map((action) => /* @__PURE__ */ jsx50(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3450
+ menu != null && /* @__PURE__ */ jsx50("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx50(
3399
3451
  Menu,
3400
3452
  {
3401
3453
  align: "right",
3402
- trigger: /* @__PURE__ */ jsx49(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx49(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3454
+ trigger: /* @__PURE__ */ jsx50(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx50(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3403
3455
  children: menu
3404
3456
  }
3405
3457
  ) })
@@ -3412,7 +3464,7 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3412
3464
  }
3413
3465
 
3414
3466
  // src/CollapsibleSection.tsx
3415
- import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
3467
+ import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
3416
3468
  var OPEN = "open";
3417
3469
  var CLOSED = "closed";
3418
3470
  function readStored(key) {
@@ -3440,30 +3492,30 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
3440
3492
  onOpenChange?.(next);
3441
3493
  };
3442
3494
  return /* @__PURE__ */ jsxs34(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
3443
- /* @__PURE__ */ jsx50(SectionHeader, { title, chevron: true, icon, isExpanded: open, trailing, actions, menu, menuLabel, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx50(Collapsible2.Trigger, {}) }),
3444
- /* @__PURE__ */ jsx50(
3495
+ /* @__PURE__ */ jsx51(SectionHeader, { title, chevron: true, icon, isExpanded: open, trailing, actions, menu, menuLabel, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx51(Collapsible2.Trigger, {}) }),
3496
+ /* @__PURE__ */ jsx51(
3445
3497
  Collapsible2.Panel,
3446
3498
  {
3447
3499
  hiddenUntilFound: true,
3448
3500
  className: COLLAPSIBLE_PANEL_CLASSES,
3449
- children: /* @__PURE__ */ jsx50("div", { className: cn("flex flex-col pt-0.5", (look === "row" || indent) && "pl-6", contentClassName), children })
3501
+ children: /* @__PURE__ */ jsx51("div", { className: cn("flex flex-col pt-0.5", (look === "row" || indent) && "pl-6", contentClassName), children })
3450
3502
  }
3451
3503
  )
3452
3504
  ] });
3453
3505
  }
3454
3506
 
3455
3507
  // src/NavTree.tsx
3456
- import { Fragment as Fragment13, jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
3508
+ import { Fragment as Fragment13, jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
3457
3509
  var NAV_TREE_INTENT_MS = 150;
3458
3510
  function holds(nodes, id) {
3459
3511
  return !!nodes && id !== void 0 && nodes.some((node) => node.id === id || holds(node.children ?? null, id));
3460
3512
  }
3461
3513
  function Line({ message }) {
3462
- return /* @__PURE__ */ jsx51("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx51(EmptyState, { scope: "section", message }) });
3514
+ return /* @__PURE__ */ jsx52("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx52(EmptyState, { scope: "section", message }) });
3463
3515
  }
3464
3516
  function Row({ node, selected, onSelect }) {
3465
- const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx51(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx51(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx51(SkeletonList, { rows: 2 }) : void 0;
3466
- return /* @__PURE__ */ jsx51(
3517
+ const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx52(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx52(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx52(SkeletonList, { rows: 2 }) : void 0;
3518
+ return /* @__PURE__ */ jsx52(
3467
3519
  NavItem,
3468
3520
  {
3469
3521
  href: node.href,
@@ -3485,7 +3537,7 @@ function Row({ node, selected, onSelect }) {
3485
3537
  );
3486
3538
  }
3487
3539
  function Group({ group, selected, onSelect, storageKey }) {
3488
- return /* @__PURE__ */ jsx51(
3540
+ return /* @__PURE__ */ jsx52(
3489
3541
  NavTreeSection,
3490
3542
  {
3491
3543
  id: group.id,
@@ -3501,7 +3553,7 @@ function Group({ group, selected, onSelect, storageKey }) {
3501
3553
  onOpenChange: group.onOpenChange,
3502
3554
  storageKey: storageKey ? `${storageKey}.${group.id}` : void 0,
3503
3555
  onIntent: group.onIntent,
3504
- children: group.nodes?.map((node) => /* @__PURE__ */ jsx51(Row, { node, selected, onSelect }, node.id))
3556
+ children: group.nodes?.map((node) => /* @__PURE__ */ jsx52(Row, { node, selected, onSelect }, node.id))
3505
3557
  }
3506
3558
  );
3507
3559
  }
@@ -3509,7 +3561,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3509
3561
  const timer = useRef11(void 0);
3510
3562
  useEffect6(() => () => clearTimeout(timer.current), []);
3511
3563
  const intent = onIntent;
3512
- return /* @__PURE__ */ jsx51(
3564
+ return /* @__PURE__ */ jsx52(
3513
3565
  "div",
3514
3566
  {
3515
3567
  className: "shrink-0 [&+&]:mt-1",
@@ -3520,7 +3572,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3520
3572
  } : void 0,
3521
3573
  onPointerLeave: intent ? () => clearTimeout(timer.current) : void 0,
3522
3574
  onFocus: intent,
3523
- children: /* @__PURE__ */ jsx51(
3575
+ children: /* @__PURE__ */ jsx52(
3524
3576
  CollapsibleSection,
3525
3577
  {
3526
3578
  title,
@@ -3535,7 +3587,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3535
3587
  icon,
3536
3588
  className: "shrink-0",
3537
3589
  contentClassName: "gap-0.5",
3538
- children: message !== void 0 ? /* @__PURE__ */ jsx51(Line, { message }) : loading ? /* @__PURE__ */ jsx51(SkeletonList, { rows: 3 }) : children
3590
+ children: message !== void 0 ? /* @__PURE__ */ jsx52(Line, { message }) : loading ? /* @__PURE__ */ jsx52(SkeletonList, { rows: 3 }) : children
3539
3591
  }
3540
3592
  )
3541
3593
  }
@@ -3543,18 +3595,18 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3543
3595
  }
3544
3596
  function NavTree({ title, titleActions, groups, children, selected, onSelect, emptyMessage = "", storageKey }) {
3545
3597
  return /* @__PURE__ */ jsxs35(Fragment13, { children: [
3546
- title && /* @__PURE__ */ jsx51(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
3547
- groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx51(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
3598
+ title && /* @__PURE__ */ jsx52(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
3599
+ groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx52(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
3548
3600
  // No words, no line: an app that says nothing when it has no groups.
3549
- emptyMessage ? /* @__PURE__ */ jsx51(Line, { message: emptyMessage }) : null
3550
- ) : groups.map((group) => /* @__PURE__ */ jsx51(Group, { group, selected, onSelect, storageKey }, group.id))
3601
+ emptyMessage ? /* @__PURE__ */ jsx52(Line, { message: emptyMessage }) : null
3602
+ ) : groups.map((group) => /* @__PURE__ */ jsx52(Group, { group, selected, onSelect, storageKey }, group.id))
3551
3603
  ] });
3552
3604
  }
3553
3605
 
3554
3606
  // src/Popover.tsx
3555
3607
  import { useMemo as useMemo4 } from "react";
3556
3608
  import { Popover as BasePopover } from "@base-ui/react/popover";
3557
- import { jsx as jsx52, jsxs as jsxs36 } from "react/jsx-runtime";
3609
+ import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
3558
3610
  var GAP5 = 4;
3559
3611
  var VIEWPORT_PAD5 = 8;
3560
3612
  function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
@@ -3571,8 +3623,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3571
3623
  actionsRef,
3572
3624
  modal: false,
3573
3625
  children: [
3574
- trigger && /* @__PURE__ */ jsx52(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
3575
- /* @__PURE__ */ jsx52(BasePopover.Portal, { children: /* @__PURE__ */ jsx52(
3626
+ trigger && /* @__PURE__ */ jsx53(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
3627
+ /* @__PURE__ */ jsx53(BasePopover.Portal, { children: /* @__PURE__ */ jsx53(
3576
3628
  BasePopover.Positioner,
3577
3629
  {
3578
3630
  anchor: anchorTarget,
@@ -3581,20 +3633,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3581
3633
  sideOffset: GAP5,
3582
3634
  collisionPadding: VIEWPORT_PAD5,
3583
3635
  className: "z-50 data-[anchor-hidden]:hidden",
3584
- children: /* @__PURE__ */ jsx52(
3636
+ children: /* @__PURE__ */ jsx53(
3585
3637
  BasePopover.Popup,
3586
3638
  {
3587
3639
  "aria-label": ariaLabel,
3588
3640
  initialFocus: trigger ? void 0 : false,
3589
3641
  finalFocus,
3590
3642
  className: cn("min-w-[180px] outline-none p-0", className),
3591
- render: /* @__PURE__ */ jsx52(MenuPanel, {}),
3592
- children: /* @__PURE__ */ jsx52(
3643
+ render: /* @__PURE__ */ jsx53(MenuPanel, {}),
3644
+ children: /* @__PURE__ */ jsx53(
3593
3645
  ScrollArea,
3594
3646
  {
3595
3647
  viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
3596
3648
  contentClassName: cn("flex flex-col p-2", contentClassName),
3597
- children: /* @__PURE__ */ jsx52(DividerInPanel.Provider, { value: true, children })
3649
+ children: /* @__PURE__ */ jsx53(DividerInPanel.Provider, { value: true, children })
3598
3650
  }
3599
3651
  )
3600
3652
  }
@@ -3608,7 +3660,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
3608
3660
 
3609
3661
  // src/SuggestionMenu.tsx
3610
3662
  import { useCallback as useCallback4, useEffect as useEffect7, useId as useId3, useImperativeHandle, useMemo as useMemo5, useRef as useRef12, useState as useState11 } from "react";
3611
- import { jsx as jsx53, jsxs as jsxs37 } from "react/jsx-runtime";
3663
+ import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
3612
3664
  function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sections, itemKey, row, onSelect, handle }) {
3613
3665
  const shown = useMemo5(() => sections.filter((section) => section.items.length > 0), [sections]);
3614
3666
  const items = useMemo5(() => shown.flatMap((section) => section.items), [shown]);
@@ -3673,7 +3725,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3673
3725
  const { label, description, leading, shortcut, hint, size } = row(item);
3674
3726
  return (
3675
3727
  // A row of a list the editor drives from its caret: focus stays in the text, so the row is no Tab stop.
3676
- /* @__PURE__ */ jsx53(
3728
+ /* @__PURE__ */ jsx54(
3677
3729
  MenuItem,
3678
3730
  {
3679
3731
  role: "option",
@@ -3700,9 +3752,9 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3700
3752
  };
3701
3753
  return (
3702
3754
  // finalFocus={false}: focus never left the text, and a list that closes because focus moved elsewhere must not pull it back (71a4577b).
3703
- /* @__PURE__ */ jsx53(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, finalFocus: false, children: /* @__PURE__ */ jsx53("div", { ref: keepFocus, id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col gap-0.5", children: shown.map((section, i) => /* @__PURE__ */ jsxs37("div", { className: "contents", children: [
3704
- i > 0 && /* @__PURE__ */ jsx53(MenuSeparator, {}),
3705
- section.label ? /* @__PURE__ */ jsx53("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx53(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
3755
+ /* @__PURE__ */ jsx54(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, finalFocus: false, children: /* @__PURE__ */ jsx54("div", { ref: keepFocus, id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col gap-0.5", children: shown.map((section, i) => /* @__PURE__ */ jsxs37("div", { className: "contents", children: [
3756
+ i > 0 && /* @__PURE__ */ jsx54(MenuSeparator, {}),
3757
+ section.label ? /* @__PURE__ */ jsx54("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx54(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
3706
3758
  ] }, section.label ?? i)) }) })
3707
3759
  );
3708
3760
  }
@@ -3710,7 +3762,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3710
3762
  // src/ShowMore.tsx
3711
3763
  import { useLayoutEffect as useLayoutEffect5, useRef as useRef13, useState as useState12 } from "react";
3712
3764
  import { IconChevronDown as IconChevronDown4, IconChevronUp } from "@tabler/icons-react";
3713
- import { jsx as jsx54, jsxs as jsxs38 } from "react/jsx-runtime";
3765
+ import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
3714
3766
  var FADE_CLASSES = { surface: "from-bg-surface", inset: "from-bg-inset" };
3715
3767
  function ShowMore({ children, maxHeight = 96, surface = "surface", action, className }) {
3716
3768
  const box = useRef13(null);
@@ -3730,22 +3782,22 @@ function ShowMore({ children, maxHeight = 96, surface = "surface", action, class
3730
3782
  return /* @__PURE__ */ jsxs38("div", { className: cn("flex flex-col items-start", className), children: [
3731
3783
  /* @__PURE__ */ jsxs38("div", { ref: box, className: cn("relative w-full", cut && "overflow-hidden"), style: cut ? { maxHeight } : void 0, onFocus: cut ? () => setOpen(true) : void 0, children: [
3732
3784
  children,
3733
- cut && /* @__PURE__ */ jsx54("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-x-0 bottom-0 h-10 bg-gradient-to-t to-transparent", FADE_CLASSES[surface]) })
3785
+ cut && /* @__PURE__ */ jsx55("div", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-x-0 bottom-0 h-10 bg-gradient-to-t to-transparent", FADE_CLASSES[surface]) })
3734
3786
  ] }),
3735
3787
  action ? /* @__PURE__ */ jsxs38("div", { className: cn("mt-1 flex w-full items-center gap-2", overflows ? "justify-between" : "justify-end"), children: [
3736
- overflows && /* @__PURE__ */ jsx54(Toggle, { open, onToggle: () => setOpen((o) => !o) }),
3737
- /* @__PURE__ */ jsx54("div", { className: "-mr-2 flex shrink-0", children: action })
3738
- ] }) : overflows && /* @__PURE__ */ jsx54(Toggle, { open, onToggle: () => setOpen((o) => !o), className: "mt-1" })
3788
+ overflows && /* @__PURE__ */ jsx55(Toggle, { open, onToggle: () => setOpen((o) => !o) }),
3789
+ /* @__PURE__ */ jsx55("div", { className: "-mr-2 flex shrink-0", children: action })
3790
+ ] }) : overflows && /* @__PURE__ */ jsx55(Toggle, { open, onToggle: () => setOpen((o) => !o), className: "mt-1" })
3739
3791
  ] });
3740
3792
  }
3741
3793
  function Toggle({ open, onToggle, className }) {
3742
3794
  const Icon = open ? IconChevronUp : IconChevronDown4;
3743
- return /* @__PURE__ */ jsx54(
3795
+ return /* @__PURE__ */ jsx55(
3744
3796
  Button,
3745
3797
  {
3746
3798
  variant: "outlined",
3747
3799
  size: "small",
3748
- leadingIcon: /* @__PURE__ */ jsx54(Icon, { stroke: 1.5, className: "size-3.5" }),
3800
+ leadingIcon: /* @__PURE__ */ jsx55(Icon, { stroke: 1.5, className: "size-3.5" }),
3749
3801
  className,
3750
3802
  "aria-expanded": open,
3751
3803
  onClick: onToggle,
@@ -3756,9 +3808,9 @@ function Toggle({ open, onToggle, className }) {
3756
3808
 
3757
3809
  // src/Toolbar.tsx
3758
3810
  import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
3759
- import { jsx as jsx55 } from "react/jsx-runtime";
3811
+ import { jsx as jsx56 } from "react/jsx-runtime";
3760
3812
  function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
3761
- const strip = /* @__PURE__ */ jsx55(
3813
+ const strip = /* @__PURE__ */ jsx56(
3762
3814
  BaseToolbar.Root,
3763
3815
  {
3764
3816
  "aria-label": ariaLabel,
@@ -3769,27 +3821,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
3769
3821
  }
3770
3822
  );
3771
3823
  if (!surface) return strip;
3772
- return /* @__PURE__ */ jsx55(MenuPanel, { className: "w-fit p-1", children: strip });
3824
+ return /* @__PURE__ */ jsx56(MenuPanel, { className: "w-fit p-1", children: strip });
3773
3825
  }
3774
3826
  function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
3775
- return /* @__PURE__ */ jsx55(
3827
+ return /* @__PURE__ */ jsx56(
3776
3828
  BaseToolbar.Button,
3777
3829
  {
3778
3830
  ref,
3779
3831
  disabled: disabled || !!disabledReason,
3780
3832
  focusableWhenDisabled: true,
3781
- render: /* @__PURE__ */ jsx55(IconButton, { disabled, disabledReason, ...props })
3833
+ render: /* @__PURE__ */ jsx56(IconButton, { disabled, disabledReason, ...props })
3782
3834
  }
3783
3835
  );
3784
3836
  }
3785
3837
  function ToolbarLink({ ref, href, ...props }) {
3786
- return /* @__PURE__ */ jsx55(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx55(IconButton, { href, ...props }) });
3838
+ return /* @__PURE__ */ jsx56(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx56(IconButton, { href, ...props }) });
3787
3839
  }
3788
3840
  function ToolbarInput({ size, ...props }) {
3789
- return /* @__PURE__ */ jsx55(BaseToolbar.Input, { render: /* @__PURE__ */ jsx55(TextInput, { size }), ...props });
3841
+ return /* @__PURE__ */ jsx56(BaseToolbar.Input, { render: /* @__PURE__ */ jsx56(TextInput, { size }), ...props });
3790
3842
  }
3791
3843
  function ToolbarSeparator({ className }) {
3792
- return /* @__PURE__ */ jsx55(
3844
+ return /* @__PURE__ */ jsx56(
3793
3845
  BaseToolbar.Separator,
3794
3846
  {
3795
3847
  orientation: "vertical",
@@ -3799,9 +3851,9 @@ function ToolbarSeparator({ className }) {
3799
3851
  }
3800
3852
 
3801
3853
  // src/ReactionPicker.tsx
3802
- import { jsx as jsx56 } from "react/jsx-runtime";
3854
+ import { jsx as jsx57 } from "react/jsx-runtime";
3803
3855
  function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
3804
- return /* @__PURE__ */ jsx56(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
3856
+ return /* @__PURE__ */ jsx57(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
3805
3857
  /*
3806
3858
  A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
3807
3859
  would become the toolbar's item and the button inside it would never
@@ -3811,14 +3863,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
3811
3863
  The tooltip names it for a pointer, `aria-label` for everything else,
3812
3864
  and both say the meaning rather than the glyph.
3813
3865
  */
3814
- /* @__PURE__ */ jsx56(
3866
+ /* @__PURE__ */ jsx57(
3815
3867
  ToolbarButton,
3816
3868
  {
3817
3869
  "aria-label": option.label,
3818
3870
  tooltip: option.label,
3819
3871
  onClick: () => onSelect(option.emoji),
3820
3872
  className: "size-7",
3821
- children: /* @__PURE__ */ jsx56("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
3873
+ children: /* @__PURE__ */ jsx57("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
3822
3874
  },
3823
3875
  option.emoji
3824
3876
  )
@@ -3827,23 +3879,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
3827
3879
 
3828
3880
  // src/PreviewCard.tsx
3829
3881
  import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
3830
- import { jsx as jsx57, jsxs as jsxs39 } from "react/jsx-runtime";
3882
+ import { jsx as jsx58, jsxs as jsxs39 } from "react/jsx-runtime";
3831
3883
  var GAP6 = 12;
3832
3884
  var VIEWPORT_PAD6 = 8;
3833
3885
  var OPEN_DELAY2 = 350;
3834
3886
  var CLOSE_DELAY = 200;
3835
3887
  function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
3836
3888
  return /* @__PURE__ */ jsxs39(BasePreviewCard.Root, { children: [
3837
- /* @__PURE__ */ jsx57(
3889
+ /* @__PURE__ */ jsx58(
3838
3890
  BasePreviewCard.Trigger,
3839
3891
  {
3840
3892
  delay,
3841
3893
  closeDelay,
3842
- render: /* @__PURE__ */ jsx57("span", { className: cn("inline-flex", wrapperClassName) }),
3894
+ render: /* @__PURE__ */ jsx58("span", { className: cn("inline-flex", wrapperClassName) }),
3843
3895
  children
3844
3896
  }
3845
3897
  ),
3846
- /* @__PURE__ */ jsx57(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx57(
3898
+ /* @__PURE__ */ jsx58(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx58(
3847
3899
  BasePreviewCard.Positioner,
3848
3900
  {
3849
3901
  side,
@@ -3851,12 +3903,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
3851
3903
  sideOffset: GAP6,
3852
3904
  collisionPadding: VIEWPORT_PAD6,
3853
3905
  className: "z-50 data-[anchor-hidden]:hidden",
3854
- children: /* @__PURE__ */ jsx57(
3906
+ children: /* @__PURE__ */ jsx58(
3855
3907
  BasePreviewCard.Popup,
3856
3908
  {
3857
3909
  className: cn("w-[360px] p-0 outline-none", className),
3858
- render: /* @__PURE__ */ jsx57(MenuPanel, {}),
3859
- children: /* @__PURE__ */ jsx57(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
3910
+ render: /* @__PURE__ */ jsx58(MenuPanel, {}),
3911
+ children: /* @__PURE__ */ jsx58(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
3860
3912
  }
3861
3913
  )
3862
3914
  }
@@ -3865,13 +3917,13 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
3865
3917
  }
3866
3918
 
3867
3919
  // src/Rail.tsx
3868
- import { jsx as jsx58 } from "react/jsx-runtime";
3920
+ import { jsx as jsx59 } from "react/jsx-runtime";
3869
3921
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
3870
- return /* @__PURE__ */ jsx58("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
3922
+ return /* @__PURE__ */ jsx59("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
3871
3923
  }
3872
3924
 
3873
3925
  // src/RailItem.tsx
3874
- import { jsx as jsx59, jsxs as jsxs40 } from "react/jsx-runtime";
3926
+ import { jsx as jsx60, jsxs as jsxs40 } from "react/jsx-runtime";
3875
3927
  function RailItem({ href, icon, label, active = false, className, onClick, ...props }) {
3876
3928
  const inApp = useInAppClick(href, onClick);
3877
3929
  return /* @__PURE__ */ jsxs40(
@@ -3883,14 +3935,14 @@ function RailItem({ href, icon, label, active = false, className, onClick, ...pr
3883
3935
  ...props,
3884
3936
  onClick: inApp,
3885
3937
  children: [
3886
- /* @__PURE__ */ jsx59(
3938
+ /* @__PURE__ */ jsx60(
3887
3939
  "div",
3888
3940
  {
3889
3941
  className: cn(
3890
3942
  "flex items-center justify-center rounded-lg p-2 transition-colors",
3891
3943
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
3892
3944
  ),
3893
- children: /* @__PURE__ */ jsx59(
3945
+ children: /* @__PURE__ */ jsx60(
3894
3946
  "span",
3895
3947
  {
3896
3948
  className: cn(
@@ -3902,14 +3954,14 @@ function RailItem({ href, icon, label, active = false, className, onClick, ...pr
3902
3954
  )
3903
3955
  }
3904
3956
  ),
3905
- /* @__PURE__ */ jsx59("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
3957
+ /* @__PURE__ */ jsx60("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
3906
3958
  ]
3907
3959
  }
3908
3960
  );
3909
3961
  }
3910
3962
 
3911
3963
  // src/Property.tsx
3912
- import { jsx as jsx60, jsxs as jsxs41 } from "react/jsx-runtime";
3964
+ import { jsx as jsx61, jsxs as jsxs41 } from "react/jsx-runtime";
3913
3965
  var VALUE_CLASSES = "contents";
3914
3966
  function Property({ label, layout = "row", children, className }) {
3915
3967
  if (layout === "stacked") {
@@ -3918,20 +3970,20 @@ function Property({ label, layout = "row", children, className }) {
3918
3970
  // Peek's topic-details sections already sit at 12px, Ship's rail was
3919
3971
  // 6px, and unifying means the bigger, calmer one.
3920
3972
  /* @__PURE__ */ jsxs41("dl", { className: cn("flex flex-col gap-3", className), children: [
3921
- /* @__PURE__ */ jsx60("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
3922
- /* @__PURE__ */ jsx60("dd", { className: VALUE_CLASSES, children })
3973
+ /* @__PURE__ */ jsx61("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
3974
+ /* @__PURE__ */ jsx61("dd", { className: VALUE_CLASSES, children })
3923
3975
  ] })
3924
3976
  );
3925
3977
  }
3926
3978
  return /* @__PURE__ */ jsxs41("dl", { className: cn("flex items-center gap-2", className), children: [
3927
- /* @__PURE__ */ jsx60("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
3928
- /* @__PURE__ */ jsx60("dd", { className: VALUE_CLASSES, children })
3979
+ /* @__PURE__ */ jsx61("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
3980
+ /* @__PURE__ */ jsx61("dd", { className: VALUE_CLASSES, children })
3929
3981
  ] });
3930
3982
  }
3931
3983
 
3932
3984
  // src/Reaction.tsx
3933
3985
  import { Toggle as Toggle2 } from "@base-ui/react/toggle";
3934
- import { jsx as jsx61, jsxs as jsxs42 } from "react/jsx-runtime";
3986
+ import { jsx as jsx62, jsxs as jsxs42 } from "react/jsx-runtime";
3935
3987
  function Reaction({ emoji, count, pressed = false, className, ...props }) {
3936
3988
  return (
3937
3989
  // @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
@@ -3957,8 +4009,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
3957
4009
  ),
3958
4010
  ...props,
3959
4011
  children: [
3960
- /* @__PURE__ */ jsx61("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
3961
- /* @__PURE__ */ jsx61("span", { className: CHIP_TEXT_CLASSES, children: count })
4012
+ /* @__PURE__ */ jsx62("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
4013
+ /* @__PURE__ */ jsx62("span", { className: CHIP_TEXT_CLASSES, children: count })
3962
4014
  ]
3963
4015
  }
3964
4016
  )
@@ -3968,7 +4020,7 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
3968
4020
  // src/SearchInput.tsx
3969
4021
  import "react";
3970
4022
  import { Input as Input3 } from "@base-ui/react/input";
3971
- import { jsx as jsx62, jsxs as jsxs43 } from "react/jsx-runtime";
4023
+ import { jsx as jsx63, jsxs as jsxs43 } from "react/jsx-runtime";
3972
4024
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
3973
4025
  return /* @__PURE__ */ jsxs43(
3974
4026
  "div",
@@ -3982,7 +4034,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
3982
4034
  className
3983
4035
  ),
3984
4036
  children: [
3985
- /* @__PURE__ */ jsx62(
4037
+ /* @__PURE__ */ jsx63(
3986
4038
  Input3,
3987
4039
  {
3988
4040
  className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
@@ -3990,40 +4042,40 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
3990
4042
  ...props
3991
4043
  }
3992
4044
  ),
3993
- shortcut && /* @__PURE__ */ jsx62(Kbd, { children: shortcut })
4045
+ shortcut && /* @__PURE__ */ jsx63(Kbd, { children: shortcut })
3994
4046
  ]
3995
4047
  }
3996
4048
  );
3997
4049
  }
3998
4050
 
3999
4051
  // src/Panel.tsx
4000
- import { jsx as jsx63, jsxs as jsxs44 } from "react/jsx-runtime";
4052
+ import { jsx as jsx64, jsxs as jsxs44 } from "react/jsx-runtime";
4001
4053
  function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
4002
4054
  return /* @__PURE__ */ jsxs44("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
4003
- /* @__PURE__ */ jsx63(ContainerHeader, { title, chevron, actions }),
4055
+ /* @__PURE__ */ jsx64(ContainerHeader, { title, chevron, actions }),
4004
4056
  broken ? (
4005
4057
  // The message takes the room the body had and centres itself in it.
4006
- /* @__PURE__ */ jsx63("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
4007
- ) : /* @__PURE__ */ jsx63(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
4008
- !broken && footer && /* @__PURE__ */ jsx63("div", { className: "shrink-0", children: footer })
4058
+ /* @__PURE__ */ jsx64("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
4059
+ ) : /* @__PURE__ */ jsx64(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
4060
+ !broken && footer && /* @__PURE__ */ jsx64("div", { className: "shrink-0", children: footer })
4009
4061
  ] });
4010
4062
  }
4011
4063
  function Panel(props) {
4012
- return /* @__PURE__ */ jsx63(
4064
+ return /* @__PURE__ */ jsx64(
4013
4065
  ErrorBoundary,
4014
4066
  {
4015
4067
  label: "panel",
4016
4068
  frame: (message) => (
4017
4069
  // Only the name comes back with the message: the actions and the footer may be what threw.
4018
- /* @__PURE__ */ jsx63(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
4070
+ /* @__PURE__ */ jsx64(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
4019
4071
  ),
4020
- children: /* @__PURE__ */ jsx63(Frame, { ...props })
4072
+ children: /* @__PURE__ */ jsx64(Frame, { ...props })
4021
4073
  }
4022
4074
  );
4023
4075
  }
4024
4076
 
4025
4077
  // src/ListColumn.tsx
4026
- import { jsx as jsx64, jsxs as jsxs45 } from "react/jsx-runtime";
4078
+ import { jsx as jsx65, jsxs as jsxs45 } from "react/jsx-runtime";
4027
4079
  function Column({ title, chevron = false, titleMenu, actions, above, collapsed = false, children, className, broken = false }) {
4028
4080
  return /* @__PURE__ */ jsxs45(
4029
4081
  "div",
@@ -4036,35 +4088,35 @@ function Column({ title, chevron = false, titleMenu, actions, above, collapsed =
4036
4088
  ),
4037
4089
  "data-collapsed": collapsed || void 0,
4038
4090
  children: [
4039
- /* @__PURE__ */ jsx64(ContainerHeader, { title, chevron, titleMenu, actions }),
4091
+ /* @__PURE__ */ jsx65(ContainerHeader, { title, chevron, titleMenu, actions }),
4040
4092
  above,
4041
4093
  broken ? (
4042
4094
  // The message takes the room the list had and centres itself in it (Katerina, 19 September).
4043
- /* @__PURE__ */ jsx64("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
4044
- ) : /* @__PURE__ */ jsx64(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
4095
+ /* @__PURE__ */ jsx65("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
4096
+ ) : /* @__PURE__ */ jsx65(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
4045
4097
  ]
4046
4098
  }
4047
4099
  );
4048
4100
  }
4049
4101
  function ListColumn(props) {
4050
- return /* @__PURE__ */ jsx64(
4102
+ return /* @__PURE__ */ jsx65(
4051
4103
  ErrorBoundary,
4052
4104
  {
4053
4105
  label: "list panel",
4054
4106
  frame: (message) => (
4055
4107
  // Only the name comes back with the message: the actions and the row above may be what threw.
4056
- /* @__PURE__ */ jsx64(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
4108
+ /* @__PURE__ */ jsx65(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
4057
4109
  ),
4058
- children: /* @__PURE__ */ jsx64(Column, { ...props })
4110
+ children: /* @__PURE__ */ jsx65(Column, { ...props })
4059
4111
  }
4060
4112
  );
4061
4113
  }
4062
4114
 
4063
4115
  // src/Tabs.tsx
4064
4116
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
4065
- import { Fragment as Fragment14, jsx as jsx65, jsxs as jsxs46 } from "react/jsx-runtime";
4117
+ import { Fragment as Fragment14, jsx as jsx66, jsxs as jsxs46 } from "react/jsx-runtime";
4066
4118
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
4067
- return /* @__PURE__ */ jsx65(
4119
+ return /* @__PURE__ */ jsx66(
4068
4120
  BaseTabs.Root,
4069
4121
  {
4070
4122
  value: active,
@@ -4072,7 +4124,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
4072
4124
  if (details.reason === "none") onChange(value);
4073
4125
  },
4074
4126
  className,
4075
- children: /* @__PURE__ */ jsx65(
4127
+ children: /* @__PURE__ */ jsx66(
4076
4128
  BaseTabs.List,
4077
4129
  {
4078
4130
  activateOnFocus: true,
@@ -4094,11 +4146,11 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
4094
4146
  tab.icon,
4095
4147
  /* @__PURE__ */ jsxs46("span", { className: "flex items-baseline", children: [
4096
4148
  tab.label,
4097
- tab.count !== void 0 ? /* @__PURE__ */ jsx65("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
4149
+ tab.count !== void 0 ? /* @__PURE__ */ jsx66("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
4098
4150
  ] }),
4099
4151
  tab.unread ? /* @__PURE__ */ jsxs46(Fragment14, { children: [
4100
- /* @__PURE__ */ jsx65(UnreadDot, { className: "h-auto w-auto" }),
4101
- /* @__PURE__ */ jsx65("span", { className: "sr-only", children: "new" })
4152
+ /* @__PURE__ */ jsx66(UnreadDot, { className: "h-auto w-auto" }),
4153
+ /* @__PURE__ */ jsx66("span", { className: "sr-only", children: "new" })
4102
4154
  ] }) : null
4103
4155
  ]
4104
4156
  },
@@ -4114,7 +4166,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
4114
4166
  import { createContext as createContext7, useContext as useContext7, useMemo as useMemo6 } from "react";
4115
4167
  import { Toast as BaseToast } from "@base-ui/react/toast";
4116
4168
  import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
4117
- import { jsx as jsx66, jsxs as jsxs47 } from "react/jsx-runtime";
4169
+ import { jsx as jsx67, jsxs as jsxs47 } from "react/jsx-runtime";
4118
4170
  var SURFACE_STYLES = {
4119
4171
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
4120
4172
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
@@ -4122,7 +4174,7 @@ var SURFACE_STYLES = {
4122
4174
  warning: "bg-warning-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
4123
4175
  error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md"
4124
4176
  };
4125
- var ICONS = {
4177
+ var ICONS2 = {
4126
4178
  success: IconCircleCheck,
4127
4179
  brand: IconCircleCheck,
4128
4180
  neutral: IconCircleCheck,
@@ -4149,17 +4201,17 @@ var pillClassName = (type, hasAction, className) => cn(
4149
4201
  className
4150
4202
  );
4151
4203
  function LeadingIcon({ type }) {
4152
- const Icon = ICONS[type];
4153
- return /* @__PURE__ */ jsx66(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
4204
+ const Icon = ICONS2[type];
4205
+ return /* @__PURE__ */ jsx67(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
4154
4206
  }
4155
4207
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
4156
4208
  const hasAction = !!(actionLabel && onAction);
4157
4209
  return /* @__PURE__ */ jsxs47("div", { className: pillClassName(type, hasAction, className), children: [
4158
4210
  /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
4159
- leadingIcon && /* @__PURE__ */ jsx66(LeadingIcon, { type }),
4160
- /* @__PURE__ */ jsx66("span", { className: LABEL_CLASSES, children: label })
4211
+ leadingIcon && /* @__PURE__ */ jsx67(LeadingIcon, { type }),
4212
+ /* @__PURE__ */ jsx67("span", { className: LABEL_CLASSES, children: label })
4161
4213
  ] }),
4162
- hasAction && /* @__PURE__ */ jsx66(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
4214
+ hasAction && /* @__PURE__ */ jsx67(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
4163
4215
  ] });
4164
4216
  }
4165
4217
  var ToastContext = createContext7(null);
@@ -4180,9 +4232,9 @@ function ToastProvider({ children }) {
4180
4232
  }),
4181
4233
  [manager]
4182
4234
  );
4183
- return /* @__PURE__ */ jsx66(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs47(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
4235
+ return /* @__PURE__ */ jsx67(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs47(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
4184
4236
  children,
4185
- /* @__PURE__ */ jsx66(BaseToast.Portal, { children: /* @__PURE__ */ jsx66(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx66(ToastList, {}) }) })
4237
+ /* @__PURE__ */ jsx67(BaseToast.Portal, { children: /* @__PURE__ */ jsx67(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx67(ToastList, {}) }) })
4186
4238
  ] }) });
4187
4239
  }
4188
4240
  function ToastList() {
@@ -4198,17 +4250,17 @@ function ToastList() {
4198
4250
  className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
4199
4251
  children: [
4200
4252
  /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
4201
- leadingIcon && /* @__PURE__ */ jsx66(LeadingIcon, { type }),
4202
- /* @__PURE__ */ jsx66(BaseToast.Title, { render: /* @__PURE__ */ jsx66("span", {}), className: LABEL_CLASSES })
4253
+ leadingIcon && /* @__PURE__ */ jsx67(LeadingIcon, { type }),
4254
+ /* @__PURE__ */ jsx67(BaseToast.Title, { render: /* @__PURE__ */ jsx67("span", {}), className: LABEL_CLASSES })
4203
4255
  ] }),
4204
- actionLabel && /* @__PURE__ */ jsx66(
4256
+ actionLabel && /* @__PURE__ */ jsx67(
4205
4257
  BaseToast.Action,
4206
4258
  {
4207
4259
  onClick: () => {
4208
4260
  onAction?.();
4209
4261
  close(toast.id);
4210
4262
  },
4211
- render: /* @__PURE__ */ jsx66(Button, { variant: "outlined", size: "small", children: actionLabel })
4263
+ render: /* @__PURE__ */ jsx67(Button, { variant: "outlined", size: "small", children: actionLabel })
4212
4264
  }
4213
4265
  )
4214
4266
  ]
@@ -4264,6 +4316,7 @@ export {
4264
4316
  InlineChip,
4265
4317
  InputChip,
4266
4318
  Kbd,
4319
+ KindIcon,
4267
4320
  Lightbox,
4268
4321
  Link,
4269
4322
  ListColumn,
@@ -4325,6 +4378,7 @@ export {
4325
4378
  isApplePlatform,
4326
4379
  richTextClassName,
4327
4380
  shortcutLabel,
4381
+ thingKindOf,
4328
4382
  useToast
4329
4383
  };
4330
4384
  //# sourceMappingURL=index.js.map