@ai-matrx/design-system 0.86.336 → 0.86.338

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 (87) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/dist/carousel.js +6 -6
  3. package/dist/{chunk-GHPUO3O7.js → chunk-5IR3BZOS.js} +2 -2
  4. package/dist/{chunk-DQUCOMAC.js → chunk-6QKT52FR.js} +2 -2
  5. package/dist/{chunk-B24DLFWR.js → chunk-B4WMMAAJ.js} +2 -2
  6. package/dist/{chunk-M34WPTPX.js → chunk-CEA6X445.js} +2 -2
  7. package/dist/{chunk-PBDQZPKV.js → chunk-CJBSBKG5.js} +2 -2
  8. package/dist/{chunk-Q2HWDJED.js → chunk-GLLPO66A.js} +2 -2
  9. package/dist/{chunk-WZC3K7SO.js → chunk-LGC6EVFE.js} +4 -4
  10. package/dist/chunk-LGC6EVFE.js.map +1 -0
  11. package/dist/{chunk-MAMZGJJ3.js → chunk-M45FEAVG.js} +23 -5
  12. package/dist/chunk-M45FEAVG.js.map +1 -0
  13. package/dist/{chunk-RGJPHRU3.js → chunk-T4IJELSS.js} +4 -4
  14. package/dist/{chunk-L5OACQXS.js → chunk-TO4ZLGDW.js} +5 -2
  15. package/dist/chunk-TO4ZLGDW.js.map +1 -0
  16. package/dist/{chunk-VQ3G6AFN.js → chunk-TWRC7NP4.js} +4 -4
  17. package/dist/{chunk-BM2YYBUO.js → chunk-UM45E3LO.js} +2 -2
  18. package/dist/{chunk-SMJGESH7.js → chunk-WFITMVDB.js} +5 -2
  19. package/dist/{chunk-SMJGESH7.js.map → chunk-WFITMVDB.js.map} +1 -1
  20. package/dist/{chunk-QOEKPR37.js → chunk-XTP6HOB6.js} +2 -2
  21. package/dist/clipboard-fallback-dialog.cjs +4 -1
  22. package/dist/clipboard-fallback-dialog.cjs.map +1 -1
  23. package/dist/clipboard-fallback-dialog.js +3 -3
  24. package/dist/controls.cjs +4 -1
  25. package/dist/controls.cjs.map +1 -1
  26. package/dist/controls.js +6 -6
  27. package/dist/data-table/data-row-inspector.js +5 -5
  28. package/dist/data-table/data-row-window.js +6 -6
  29. package/dist/data-table/index.cjs +4 -1
  30. package/dist/data-table/index.cjs.map +1 -1
  31. package/dist/data-table/index.js +9 -9
  32. package/dist/data-table/layered-filter-builder.cjs +4 -1
  33. package/dist/data-table/layered-filter-builder.cjs.map +1 -1
  34. package/dist/data-table/layered-filter-builder.js +2 -2
  35. package/dist/data-table/pagination.cjs +4 -1
  36. package/dist/data-table/pagination.cjs.map +1 -1
  37. package/dist/data-table/pagination.js +3 -3
  38. package/dist/data-table/uuid-cell.js +3 -3
  39. package/dist/desktop.cjs +4 -1
  40. package/dist/desktop.cjs.map +1 -1
  41. package/dist/desktop.js +5 -5
  42. package/dist/email-input-dialog.cjs +4 -1
  43. package/dist/email-input-dialog.cjs.map +1 -1
  44. package/dist/email-input-dialog.js +2 -2
  45. package/dist/index.cjs +27 -3
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +4 -3
  48. package/dist/index.d.ts +4 -3
  49. package/dist/index.js +9 -9
  50. package/dist/item.cjs +5 -2
  51. package/dist/item.cjs.map +1 -1
  52. package/dist/item.d.cts +5 -3
  53. package/dist/item.d.ts +5 -3
  54. package/dist/item.js +4 -4
  55. package/dist/lite-table.js +2 -2
  56. package/dist/menu-look.cjs +4 -1
  57. package/dist/menu-look.cjs.map +1 -1
  58. package/dist/menu-look.css +8 -0
  59. package/dist/menu-look.d.cts +4 -1
  60. package/dist/menu-look.d.ts +4 -1
  61. package/dist/menu-look.js +1 -1
  62. package/dist/record-list.cjs +5 -2
  63. package/dist/record-list.cjs.map +1 -1
  64. package/dist/record-list.d.cts +5 -3
  65. package/dist/record-list.d.ts +5 -3
  66. package/dist/record-list.js +4 -4
  67. package/dist/settings.cjs +4 -1
  68. package/dist/settings.cjs.map +1 -1
  69. package/dist/settings.js +3 -3
  70. package/dist/text-input-dialog.cjs +4 -1
  71. package/dist/text-input-dialog.cjs.map +1 -1
  72. package/dist/text-input-dialog.js +2 -2
  73. package/dist/writing-field.js +3 -3
  74. package/package.json +2 -2
  75. package/dist/chunk-L5OACQXS.js.map +0 -1
  76. package/dist/chunk-MAMZGJJ3.js.map +0 -1
  77. package/dist/chunk-WZC3K7SO.js.map +0 -1
  78. /package/dist/{chunk-GHPUO3O7.js.map → chunk-5IR3BZOS.js.map} +0 -0
  79. /package/dist/{chunk-DQUCOMAC.js.map → chunk-6QKT52FR.js.map} +0 -0
  80. /package/dist/{chunk-B24DLFWR.js.map → chunk-B4WMMAAJ.js.map} +0 -0
  81. /package/dist/{chunk-M34WPTPX.js.map → chunk-CEA6X445.js.map} +0 -0
  82. /package/dist/{chunk-PBDQZPKV.js.map → chunk-CJBSBKG5.js.map} +0 -0
  83. /package/dist/{chunk-Q2HWDJED.js.map → chunk-GLLPO66A.js.map} +0 -0
  84. /package/dist/{chunk-RGJPHRU3.js.map → chunk-T4IJELSS.js.map} +0 -0
  85. /package/dist/{chunk-VQ3G6AFN.js.map → chunk-TWRC7NP4.js.map} +0 -0
  86. /package/dist/{chunk-BM2YYBUO.js.map → chunk-UM45E3LO.js.map} +0 -0
  87. /package/dist/{chunk-QOEKPR37.js.map → chunk-XTP6HOB6.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-AJ6BAYEN.js";
5
5
  import {
6
6
  Input
7
- } from "./chunk-GHPUO3O7.js";
7
+ } from "./chunk-5IR3BZOS.js";
8
8
  import {
9
9
  Drawer,
10
10
  DrawerContent,
@@ -34,7 +34,7 @@ import "./chunk-LEPD6TV7.js";
34
34
  import "./chunk-BD77DHUO.js";
35
35
  import "./chunk-BKCJUFD3.js";
36
36
  import "./chunk-MOZRIHJF.js";
37
- import "./chunk-SMJGESH7.js";
37
+ import "./chunk-WFITMVDB.js";
38
38
  import "./chunk-WAT2XW7L.js";
39
39
  import {
40
40
  Button
@@ -20,7 +20,7 @@ import {
20
20
  AlertDialogHeader,
21
21
  AlertDialogTitle,
22
22
  Tile
23
- } from "./chunk-B24DLFWR.js";
23
+ } from "./chunk-B4WMMAAJ.js";
24
24
  import "./chunk-DRSBLHOF.js";
25
25
  import {
26
26
  Dialog,
@@ -48,14 +48,14 @@ import {
48
48
  import {
49
49
  Field,
50
50
  Textarea
51
- } from "./chunk-QOEKPR37.js";
51
+ } from "./chunk-XTP6HOB6.js";
52
52
  import "./chunk-BD77DHUO.js";
53
53
  import "./chunk-BKCJUFD3.js";
54
54
  import "./chunk-PIQJULQB.js";
55
55
  import "./chunk-MOZRIHJF.js";
56
56
  import "./chunk-X6ZRHJQP.js";
57
57
  import "./chunk-BNXNIN2S.js";
58
- import "./chunk-SMJGESH7.js";
58
+ import "./chunk-WFITMVDB.js";
59
59
  import "./chunk-WAT2XW7L.js";
60
60
  import "./chunk-7IOSA55D.js";
61
61
  import "./chunk-FXXSZNER.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/design-system",
3
- "version": "0.86.336",
3
+ "version": "0.86.338",
4
4
  "description": "AI Matrx semantic React primitives shared across Vite, Next.js, desktop, and customer-built applications.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -776,5 +776,5 @@
776
776
  ],
777
777
  "layer": 2
778
778
  },
779
- "gitHead": "1273dc696288f11ece2552257206a1e0cfdb28db"
779
+ "gitHead": "82d533cb27341af7e4570484a5e978526f6ab63d"
780
780
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/menu-look.tsx"],"sourcesContent":["\"use client\";\n/**\n * `@ai-matrx/design-system/menu-look` — THE ONE MENU LOOK (Arman, 2026-10-23: the header \"…\", every\n * crumb dropdown and every Alchemy dropdown are \"the IDENTICAL dropdown that I use for Alchemy for size\n * and style\" — the right-click menu).\n *\n * Four families, one look:\n * - `MENU_LOOK_CLASS` / `MenuLookRowBody` / `MenuLookIconSlot`: the class names and the inside of a row,\n * used by @ai-matrx/context-menu's MenuPanel (its own non-Radix renderer, the right-click menu);\n * - THE DROPDOWN — `MenuLookContent` / `MenuLookSubContent` / `MenuLookItem` / `MenuLookSubTrigger` /\n * `MenuLookCheckboxItem` / `MenuLookRadioGroup` / `MenuLookRadioItem` / `MenuLookLabel` /\n * `MenuLookSeparator` / `MenuLookSearch` (+ `MenuLookSub`): the panel and rows on the Radix dropdown\n * (keyboard, typeahead, focus return, collision padding) — Alchemy's dropdowns, the frame's \"…\" and\n * crumb menus, a row's \"…\" (ItemMenu);\n * - THE RIGHT-CLICK — `MenuLookContext*`: the SAME rows on the Radix context menu (a row's right-click,\n * ItemContextMenu without a host menu);\n * - THE PANEL — `MenuLookPanel` / `MenuLookPopoverContent` / `MenuLookPanelItem` /\n * `MenuLookPanelControlRow` / `MenuLookPanelHeader` / `MenuLookPanelDisclosure` /\n * `MenuLookPanelLabel` / `MenuLookPanelSeparator`: the same panel and rows WITHOUT a Radix menu, for a\n * popover or sheet that also holds controls (a theme switch, a Switch, a search list) — the account\n * rail's Settings, Organization and account menus and the frame's admin menu.\n * Every measurement lives once, in `menu-look.css` (shipped inside `styles.css`): 280px panel, 30px rows,\n * 13px text on a 1.25 line, 16px icons, 4px/8px row padding, 10px corners. No part takes a `className`.\n *\n * ONE LEFT EDGE (Arman, 2026-10-23: \"get rid of the HORRIBLE and ugly indentation\"): a row without a\n * glyph draws no icon column, the current row is marked with a check at its END (`current`), and the\n * search is the menu's own header row whose text starts where every row's text starts.\n */\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\nimport { DropdownMenuContent, DropdownMenuSubContent } from \"./dropdown-menu\";\nimport { ContextMenuContent, ContextMenuSubContent } from \"./context-menu\";\nimport { PopoverContent } from \"./popover\";\nimport { RadixCheckIcon, RadixChevronDownIcon, RadixChevronRightIcon } from \"./icons\";\nimport { useScrollFade } from \"./use-scroll-fade\";\n\n/** The look's measurements (what `menu-look.css` draws), for tests and hosts that size around a menu. */\nexport const MENU_LOOK = {\n width: 280,\n largeWidth: 360,\n rowHeight: 30,\n sheetRowHeight: 44,\n fontSize: 13,\n lineHeight: 1.25,\n icon: 16,\n headerMark: 28,\n rowPaddingY: 4,\n rowPaddingX: 8,\n radius: 10,\n} as const;\n\n/** The look's class names — the ONLY classes a menu part wears. */\nexport const MENU_LOOK_CLASS = {\n panel: \"cm-menu\",\n item: \"cm-item\",\n iconSlot: \"cm-icon-slot\",\n icon: \"cm-icon\",\n text: \"cm-text\",\n label: \"cm-label\",\n hint: \"cm-hint\",\n current: \"cm-current\",\n chevron: \"cm-chevron\",\n search: \"cm-search\",\n trail: \"cm-trail\",\n badge: \"cm-badge\",\n shortcut: \"cm-shortcut\",\n control: \"cm-control\",\n divider: \"cm-divider\",\n sectionLabel: \"cm-section-label\",\n header: \"cm-header\",\n headerMark: \"cm-header-mark\",\n headerText: \"cm-header-text\",\n headerTitle: \"cm-header-title\",\n headerSubtitle: \"cm-header-subtitle\",\n danger: \"cm-danger\",\n dimmed: \"cm-dimmed\",\n} as const;\n\nexport type MenuLookSize = \"standard\" | \"large\";\nexport type MenuLookDensity = \"comfortable\" | \"compact\";\n\n/** The 16px icon column of a row that has a glyph (an empty slot draws nothing: no reserved gutter). */\nexport function MenuLookIconSlot({ children }: { children?: React.ReactNode }): React.ReactElement {\n return <span className={MENU_LOOK_CLASS.iconSlot}>{children}</span>;\n}\n\nexport interface MenuLookRowBodyProps {\n /** The glyph (any 16px svg; the slot sizes it). Omitted → no icon column; the text starts the row. */\n icon?: React.ReactNode | undefined;\n label: React.ReactNode;\n /** Hover text for the label (a long description stays out of the row: no \"novels\" in menus). */\n labelTitle?: string | undefined;\n /** A muted second line under the label. */\n description?: React.ReactNode | undefined;\n /** A muted end-of-row hint (a trail, a shortcut word). */\n trail?: React.ReactNode | undefined;\n /** A small outlined tag at the row's end (\"New\", \"Beta\", a count). */\n badge?: React.ReactNode | undefined;\n /** The row's key, at its end (\"⌘C\", \"R\"). */\n shortcut?: React.ReactNode | undefined;\n /** The row the person is on now: medium weight and a check at the row's end (never a left gutter). */\n current?: boolean | undefined;\n}\n\n/** The inside of a row: icon (when given), label (+ second line), end hint, badge, key, current check. */\nexport function MenuLookRowBody({ icon, label, labelTitle, description, trail, badge, shortcut, current }: MenuLookRowBodyProps): React.ReactElement {\n return (\n <>\n {icon ? <MenuLookIconSlot>{icon}</MenuLookIconSlot> : null}\n <span className={MENU_LOOK_CLASS.text}>\n <span className={MENU_LOOK_CLASS.label} title={labelTitle}>{label}</span>\n {description ? <span className={MENU_LOOK_CLASS.hint}>{description}</span> : null}\n </span>\n {trail ? <span className={MENU_LOOK_CLASS.trail}>{trail}</span> : null}\n {badge ? <span className={MENU_LOOK_CLASS.badge}>{badge}</span> : null}\n {shortcut ? <kbd className={MENU_LOOK_CLASS.shortcut}>{shortcut}</kbd> : null}\n {current ? <RadixCheckIcon className={MENU_LOOK_CLASS.current} aria-hidden=\"true\" data-menu-current-mark=\"\" /> : null}\n </>\n );\n}\n\n/** A row's classes: the look's row, plus its danger / dimmed marks. */\nexport function menuLookItemClass({ destructive, dimmed }: { destructive?: boolean | undefined; dimmed?: boolean | undefined } = {}): string {\n return `${MENU_LOOK_CLASS.item}${destructive ? ` ${MENU_LOOK_CLASS.danger}` : \"\"}${dimmed ? ` ${MENU_LOOK_CLASS.dimmed}` : \"\"}`;\n}\n\ntype DataAttributes = { [dataAttribute: `data-${string}`]: string | undefined };\n\ninterface PanelLookProps {\n /** \"standard\" (280px, the right-click menu) or \"large\" (360px, 36px rows). */\n size?: MenuLookSize | undefined;\n density?: MenuLookDensity | undefined;\n}\n\n/**\n * A submenu panel's fit: `\"menu\"` (the look's width and padding) or `\"content\"` — the panel holds a\n * host's own surface (the Alchemy palette): its width, no padding, and the popover height the surface\n * reads mapped to the room this menu measured.\n */\nexport type MenuLookSubFit = \"menu\" | \"content\";\n\n// ── THE DROPDOWN and THE RIGHT-CLICK: one set of rows over either Radix menu ──────────────────────\n\ntype ContentProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuContent>, \"className\" | \"surface\">;\n\nexport interface MenuLookContentProps extends ContentProps, PanelLookProps, DataAttributes {\n /**\n * A LONG MENU SAYS SO, IN WORDS (FIX-Q13, production `/agents/all` at 1024x768: a record's \"…\" hid\n * its Delete below the fold and read as dead). Given, the panel is a frame that does not scroll, the\n * rows scroll inside it, and a bar with these words (\"More actions below\") sits at its bottom edge\n * whenever there is more below — a press scrolls to the end. Measured: a menu that fits shows nothing.\n */\n moreBelowLabel?: string | undefined;\n}\n\n/** The rows' scroller and its \"more below\" bar, for a panel that declares its overflow. */\nfunction DeclaredOverflow({ label, children }: { label: string; children: React.ReactNode }): React.ReactElement {\n const fade = useScrollFade();\n const viewport = React.useRef<HTMLDivElement | null>(null);\n const setViewport = React.useCallback(\n (node: HTMLDivElement | null) => {\n viewport.current = node;\n fade.ref(node);\n },\n [fade.ref],\n );\n return (\n <>\n <div ref={setViewport} className=\"cm-viewport\" data-slot=\"menu-look-viewport\">\n {children}\n </div>\n {fade.state.bottom ? (\n <button\n type=\"button\"\n className=\"cm-more-below\"\n data-slot=\"menu-look-more-below\"\n // Not a menu item: never roving focus or type-ahead; Escape and arrows stay the list's.\n tabIndex={-1}\n aria-hidden=\"true\"\n // Radix would otherwise close the menu on the press that starts this click.\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => viewport.current?.scrollTo({ top: viewport.current.scrollHeight, behavior: \"smooth\" })}\n >\n <RadixChevronDownIcon aria-hidden=\"true\" />\n {label}\n </button>\n ) : null}\n </>\n );\n}\n\n/** The menu's panel on the Radix dropdown (portalled, capped at the room Radix measured, scrolls past it). */\nexport const MenuLookContent = React.forwardRef<HTMLDivElement, MenuLookContentProps>(function MenuLookContent(\n { size = \"standard\", density = \"comfortable\", moreBelowLabel, children, ...props },\n ref,\n) {\n return (\n <DropdownMenuContent\n ref={ref}\n surface=\"solid\"\n data-menu-look=\"\"\n data-menu-family=\"dropdown\"\n data-size={size}\n data-density={density}\n {...(moreBelowLabel ? { \"data-overflow\": \"declared\" } : {})}\n {...props}\n className={MENU_LOOK_CLASS.panel}\n >\n {moreBelowLabel ? <DeclaredOverflow label={moreBelowLabel}>{children}</DeclaredOverflow> : children}\n </DropdownMenuContent>\n );\n});\n\ntype SubContentProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuSubContent>, \"className\" | \"surface\">;\n\nexport interface MenuLookSubContentProps extends SubContentProps, PanelLookProps, DataAttributes {\n fit?: MenuLookSubFit | undefined;\n}\n\n/** A submenu's panel: the same panel, as wide as the menu it opens from. */\nexport const MenuLookSubContent = React.forwardRef<HTMLDivElement, MenuLookSubContentProps>(function MenuLookSubContent(\n { size = \"standard\", density = \"comfortable\", fit = \"menu\", ...props },\n ref,\n) {\n return (\n <DropdownMenuSubContent\n ref={ref}\n surface=\"solid\"\n data-menu-look=\"\"\n data-menu-family=\"dropdown\"\n data-size={size}\n data-density={density}\n data-fit={fit}\n {...props}\n className={MENU_LOOK_CLASS.panel}\n />\n );\n});\n\ntype ContextContentProps = Omit<React.ComponentPropsWithoutRef<typeof ContextMenuContent>, \"className\">;\n\nexport interface MenuLookContextContentProps extends ContextContentProps, PanelLookProps, DataAttributes {}\n\n/** The right-click menu's panel on the Radix context menu: the dropdown's panel, opened at the pointer. */\nexport const MenuLookContextContent = React.forwardRef<HTMLDivElement, MenuLookContextContentProps>(function MenuLookContextContent(\n { size = \"standard\", density = \"comfortable\", ...props },\n ref,\n) {\n return (\n <ContextMenuContent\n ref={ref}\n data-menu-look=\"\"\n data-menu-family=\"context\"\n data-size={size}\n data-density={density}\n {...props}\n className={MENU_LOOK_CLASS.panel}\n />\n );\n});\n\ntype ContextSubContentProps = Omit<React.ComponentPropsWithoutRef<typeof ContextMenuSubContent>, \"className\">;\n\nexport interface MenuLookContextSubContentProps extends ContextSubContentProps, PanelLookProps, DataAttributes {\n fit?: MenuLookSubFit | undefined;\n}\n\n/** A right-click submenu's panel. */\nexport const MenuLookContextSubContent = React.forwardRef<HTMLDivElement, MenuLookContextSubContentProps>(function MenuLookContextSubContent(\n { size = \"standard\", density = \"comfortable\", fit = \"menu\", ...props },\n ref,\n) {\n return (\n <ContextMenuSubContent\n ref={ref}\n data-menu-look=\"\"\n data-menu-family=\"context\"\n data-size={size}\n data-density={density}\n data-fit={fit}\n {...props}\n className={MENU_LOOK_CLASS.panel}\n />\n );\n});\n\ntype ItemProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>, \"className\" | \"children\" | \"asChild\">;\n\nexport interface MenuLookItemProps extends ItemProps, MenuLookRowBodyProps, DataAttributes {\n destructive?: boolean | undefined;\n /** Drawn dimmed (a greyed verb whose reason is the row's tooltip); still focusable. */\n dimmed?: boolean | undefined;\n /** A real link: the row is an `<a>` (a modified click keeps the browser's link behaviour). */\n href?: string | undefined;\n target?: string | undefined;\n /** Props for the `<a>` (aria-current, title, onClick). */\n linkProps?: undefined | Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\" | \"target\" | \"className\" | \"children\">;\n}\n\ntype SubTriggerProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger>, \"className\" | \"children\" | \"asChild\">;\n\nexport interface MenuLookSubTriggerProps extends SubTriggerProps, MenuLookRowBodyProps, DataAttributes {}\n\ntype CheckboxProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>, \"className\" | \"children\" | \"asChild\">;\n\nexport interface MenuLookCheckboxItemProps extends CheckboxProps, MenuLookRowBodyProps, DataAttributes {}\n\ntype RadioProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>, \"className\" | \"children\" | \"asChild\">;\n\nexport interface MenuLookRadioItemProps extends RadioProps, Omit<MenuLookRowBodyProps, \"current\">, DataAttributes {}\n\ntype LabelPrimitiveProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>, \"className\">;\n\nexport interface MenuLookLabelProps extends LabelPrimitiveProps {\n /** A muted line under the heading (a menu's header: the record it acts on). */\n description?: React.ReactNode | undefined;\n}\n\ntype SeparatorProps = Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>, \"className\">;\n\n/** The parts both Radix menus share (the context menu's are the same components under other names). */\ninterface MenuPrimitives {\n Item: typeof DropdownMenuPrimitive.Item;\n SubTrigger: typeof DropdownMenuPrimitive.SubTrigger;\n CheckboxItem: typeof DropdownMenuPrimitive.CheckboxItem;\n RadioItem: typeof DropdownMenuPrimitive.RadioItem;\n ItemIndicator: typeof DropdownMenuPrimitive.ItemIndicator;\n Label: typeof DropdownMenuPrimitive.Label;\n Separator: typeof DropdownMenuPrimitive.Separator;\n}\n\n/** The rows, drawn once, over either Radix menu — so a row's \"…\" and its right-click are one look. */\nfunction menuLookRows(P: MenuPrimitives, family: \"dropdown-menu\" | \"context-menu\") {\n /** One row: icon, label (+ optional second line), optional end hint; a link when given `href`. */\n const Item = React.forwardRef<HTMLDivElement, MenuLookItemProps>(function MenuLookItem(\n { icon, label, labelTitle, description, trail, badge, shortcut, current, destructive, dimmed, href, target, linkProps, ...props },\n ref,\n ) {\n const className = menuLookItemClass({ destructive, dimmed });\n const body = <MenuLookRowBody icon={icon} label={label} labelTitle={labelTitle} description={description} trail={trail} badge={badge} shortcut={shortcut} current={current} />;\n const mark = current ? { \"data-current\": \"\" } : {};\n if (href) {\n return (\n <P.Item ref={ref} asChild data-slot={`${family}-item`} {...props} {...mark} className={className}>\n <a href={href} target={target} rel={target === \"_blank\" ? \"noopener noreferrer\" : undefined} {...linkProps}>\n {body}\n </a>\n </P.Item>\n );\n }\n return (\n <P.Item ref={ref} data-slot={`${family}-item`} {...props} {...mark} className={className}>\n {body}\n </P.Item>\n );\n });\n\n /**\n * A row that opens a submenu: the same row (icon slot, the standard gap, one left edge) with the\n * look's chevron at its END (`cm-chevron`, 16px, muted) — never a bare SubTrigger whose icon touches\n * its label.\n */\n const SubTrigger = React.forwardRef<HTMLDivElement, MenuLookSubTriggerProps>(function MenuLookSubTrigger(\n { icon, label, labelTitle, description, trail, badge, shortcut, current, ...props },\n ref,\n ) {\n return (\n <P.SubTrigger ref={ref} data-slot={`${family}-sub-trigger`} {...props} {...(current ? { \"data-current\": \"\" } : {})} className={MENU_LOOK_CLASS.item}>\n <MenuLookRowBody icon={icon} label={label} labelTitle={labelTitle} description={description} trail={trail} badge={badge} shortcut={shortcut} />\n <RadixChevronRightIcon className={MENU_LOOK_CLASS.chevron} aria-hidden=\"true\" />\n </P.SubTrigger>\n );\n });\n\n /** A toggle row: a check in the icon slot while on (the right-click menu's toggle), else its icon — a\n * toggle keeps its column either way, so switching it never moves its label. */\n const CheckboxItem = React.forwardRef<HTMLDivElement, MenuLookCheckboxItemProps>(function MenuLookCheckboxItem(\n { icon, label, labelTitle, description, trail, badge, shortcut, checked, ...props },\n ref,\n ) {\n const on = checked === true;\n return (\n <P.CheckboxItem ref={ref} {...(checked === undefined ? {} : { checked })} {...props} className={MENU_LOOK_CLASS.item}>\n <MenuLookRowBody icon={on ? <RadixCheckIcon className={MENU_LOOK_CLASS.icon} /> : (icon ?? <span className={MENU_LOOK_CLASS.icon} aria-hidden=\"true\" />)} label={label} labelTitle={labelTitle} description={description} trail={trail} badge={badge} shortcut={shortcut} />\n </P.CheckboxItem>\n );\n });\n\n /** A one-of row: the chosen one is marked like the current row — medium weight and a check at the\n * row's END — so no row reserves a left gutter for a dot. */\n const RadioItem = React.forwardRef<HTMLDivElement, MenuLookRadioItemProps>(function MenuLookRadioItem(\n { icon, label, labelTitle, description, trail, badge, shortcut, ...props },\n ref,\n ) {\n return (\n <P.RadioItem ref={ref} {...props} className={MENU_LOOK_CLASS.item}>\n <MenuLookRowBody icon={icon} label={label} labelTitle={labelTitle} description={description} trail={trail} badge={badge} shortcut={shortcut} />\n <P.ItemIndicator className={MENU_LOOK_CLASS.current} data-menu-current-mark=\"\">\n <RadixCheckIcon aria-hidden=\"true\" />\n </P.ItemIndicator>\n </P.RadioItem>\n );\n });\n\n /** A section heading (\"Copy\", \"Brands\", \"Pages\"), with an optional muted line under it. */\n const Label = React.forwardRef<HTMLDivElement, MenuLookLabelProps>(function MenuLookLabel(\n { description, children, ...props },\n ref,\n ) {\n if (!description) return <P.Label ref={ref} {...props} className={MENU_LOOK_CLASS.sectionLabel}>{children}</P.Label>;\n return (\n <P.Label ref={ref} {...props} data-has-hint=\"\" className={MENU_LOOK_CLASS.sectionLabel}>\n <span>{children}</span>\n <span className={MENU_LOOK_CLASS.hint}>{description}</span>\n </P.Label>\n );\n });\n\n /** The line between sections. */\n const Separator = React.forwardRef<HTMLDivElement, SeparatorProps>(function MenuLookSeparator(props, ref) {\n return <P.Separator ref={ref} {...props} className={MENU_LOOK_CLASS.divider} />;\n });\n\n return { Item, SubTrigger, CheckboxItem, RadioItem, Label, Separator };\n}\n\nconst dropdownRows = menuLookRows(DropdownMenuPrimitive, \"dropdown-menu\");\nconst contextRows = menuLookRows(ContextMenuPrimitive as unknown as MenuPrimitives, \"context-menu\");\n\nexport const MenuLookItem = dropdownRows.Item;\n/** Holds a submenu: `MenuLookSub` > `MenuLookSubTrigger` + `MenuLookSubContent`. */\nexport const MenuLookSub = DropdownMenuPrimitive.Sub;\nexport const MenuLookSubTrigger = dropdownRows.SubTrigger;\nexport const MenuLookCheckboxItem = dropdownRows.CheckboxItem;\n/** A group of one-of rows (`MenuLookRadioItem`); the host owns `value` / `onValueChange`. */\nexport const MenuLookRadioGroup = DropdownMenuPrimitive.RadioGroup;\nexport const MenuLookRadioItem = dropdownRows.RadioItem;\nexport const MenuLookLabel = dropdownRows.Label;\nexport const MenuLookSeparator = dropdownRows.Separator;\n\n/** The right-click twins of the dropdown rows — identical rows, the Radix context menu underneath. */\nexport const MenuLookContextItem = contextRows.Item;\nexport const MenuLookContextSub = ContextMenuPrimitive.Sub;\nexport const MenuLookContextSubTrigger = contextRows.SubTrigger;\nexport const MenuLookContextCheckboxItem = contextRows.CheckboxItem;\nexport const MenuLookContextRadioGroup = ContextMenuPrimitive.RadioGroup;\nexport const MenuLookContextRadioItem = contextRows.RadioItem;\nexport const MenuLookContextLabel = contextRows.Label;\nexport const MenuLookContextSeparator = contextRows.Separator;\n\n// ── THE PANEL: the same panel and rows with no Radix menu (a popover or sheet that holds controls) ──\n\n/**\n * Where a panel sits: `\"floating\"` draws the menu's own box (border, popover fill, shadow, 280px) — a\n * CSS-toggled menu, or a host whose popover draws nothing; `\"sheet\"` draws no box (a phone's bottom\n * sheet, or a host popover that is already the box) and gives its rows 44px touch height.\n */\nexport type MenuLookPanelSurface = \"floating\" | \"sheet\";\n\nexport interface MenuLookPanelProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\">,\n PanelLookProps,\n DataAttributes {\n surface?: MenuLookPanelSurface | undefined;\n /**\n * `\"lg\"`: below the large breakpoint (1024px) the floating panel fills the width its host gives it —\n * a CSS-toggled menu that becomes a bottom-anchored sheet on a phone (AppShell's account menu).\n */\n fillBelow?: \"lg\" | undefined;\n}\n\n/** The menu's panel as a plain element: its rows are `MenuLookPanel*` parts. Role `menu` by default. */\nexport const MenuLookPanel = React.forwardRef<HTMLDivElement, MenuLookPanelProps>(function MenuLookPanel(\n { size = \"standard\", density = \"comfortable\", surface = \"floating\", fillBelow, role = \"menu\", ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n role={role}\n data-menu-look=\"\"\n data-menu-family=\"panel\"\n data-surface={surface}\n {...(fillBelow ? { \"data-fill-below\": fillBelow } : {})}\n data-size={size}\n data-density={density}\n {...props}\n className={MENU_LOOK_CLASS.panel}\n />\n );\n});\n\ntype PopoverProps = Omit<React.ComponentPropsWithoutRef<typeof PopoverContent>, \"className\" | \"surface\" | \"width\" | \"padding\" | \"sizing\">;\n\nexport interface MenuLookPopoverContentProps extends PopoverProps, PanelLookProps, DataAttributes {}\n\n/**\n * The panel IS the popover: a Radix popover (outside click, Esc, focus return, collision padding)\n * wearing the menu's box — one element, never a popover box around a menu box. Role `menu`.\n */\nexport const MenuLookPopoverContent = React.forwardRef<HTMLDivElement, MenuLookPopoverContentProps>(function MenuLookPopoverContent(\n { size = \"standard\", density = \"comfortable\", role = \"menu\", ...props },\n ref,\n) {\n return (\n <PopoverContent\n ref={ref}\n role={role}\n surface=\"solid\"\n padding=\"none\"\n animated\n data-menu-look=\"\"\n data-menu-family=\"panel\"\n data-in-popover=\"\"\n data-surface=\"floating\"\n data-size={size}\n data-density={density}\n {...props}\n className={MENU_LOOK_CLASS.panel}\n />\n );\n});\n\ntype LinkComponent = React.ElementType;\n\ninterface PanelRowMarks {\n destructive?: boolean | undefined;\n /** Drawn dimmed (a greyed verb whose reason is the row's tooltip); still pressable. */\n dimmed?: boolean | undefined;\n}\n\nexport interface MenuLookPanelItemProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"className\" | \"style\" | \"children\" | \"type\">,\n MenuLookRowBodyProps,\n PanelRowMarks,\n DataAttributes {\n /**\n * A toggle row's state (a tool that is showing): `aria-pressed`, and while on it reads like the\n * current row (medium weight, the check at its end).\n */\n pressed?: boolean | undefined;\n /** A link: the row is an anchor (or `as`, the host's link component — Next's Link, an app link). */\n href?: string | undefined;\n target?: string | undefined;\n rel?: string | undefined;\n /** The link component for `href` (it receives `href`, `className`, `role`, `onClick`, children). */\n as?: LinkComponent | undefined;\n /** Extra props for the link component (`prefetch={false}`, `aria-current`). */\n linkProps?: Record<string, unknown> | undefined;\n}\n\n/** A panel row: a button, or a link with `href`. Same row as the dropdown's (`cm-item`). */\nexport const MenuLookPanelItem = React.forwardRef<HTMLElement, MenuLookPanelItemProps>(function MenuLookPanelItem(\n { icon, label, labelTitle, description, trail, badge, shortcut, current, pressed, destructive, dimmed, href, target, rel, as, linkProps, onClick, role = \"menuitem\", ...props },\n ref,\n) {\n const marked = Boolean(current || pressed);\n const body = <MenuLookRowBody icon={icon} label={label} labelTitle={labelTitle} description={description} trail={trail} badge={badge} shortcut={shortcut} current={marked} />;\n const className = menuLookItemClass({ destructive, dimmed });\n const mark = marked ? { \"data-current\": \"\" } : {};\n if (href) {\n const Link = as ?? \"a\";\n return (\n <Link\n ref={ref}\n href={href}\n target={target}\n rel={rel ?? (target === \"_blank\" ? \"noopener noreferrer\" : undefined)}\n role={role}\n onClick={onClick}\n {...props}\n {...linkProps}\n {...mark}\n className={className}\n >\n {body}\n </Link>\n );\n }\n return (\n <button\n ref={ref as React.Ref<HTMLButtonElement>}\n type=\"button\"\n role={role}\n onClick={onClick}\n {...(pressed === undefined ? {} : { \"aria-pressed\": pressed })}\n {...props}\n {...mark}\n className={className}\n >\n {body}\n </button>\n );\n});\n\nexport interface MenuLookPanelControlRowProps\n extends Omit<React.HTMLAttributes<HTMLElement>, \"className\" | \"style\" | \"children\">,\n Pick<MenuLookRowBodyProps, \"icon\" | \"label\" | \"description\">,\n DataAttributes {\n /** The row's own control at its end: a `Switch`, a `SegmentedControl`, a count. */\n control: React.ReactNode;\n /** `\"label\"` when the whole row should press its control (a Switch); default `\"div\"`. */\n as?: \"div\" | \"label\" | undefined;\n}\n\n/**\n * A row that holds a control instead of being one (Theme: Light | Dark | Device; Standard view with its\n * Switch): the same icon slot, label and left edge as every row, the control at its END, and no hover\n * fill (the control answers the pointer, not the row).\n */\nexport const MenuLookPanelControlRow = React.forwardRef<HTMLElement, MenuLookPanelControlRowProps>(function MenuLookPanelControlRow(\n { icon, label, description, control, as = \"div\", ...props },\n ref,\n) {\n const Row = as;\n return (\n <Row ref={ref as React.Ref<never>} data-control-row=\"\" {...props} className={MENU_LOOK_CLASS.item}>\n <MenuLookRowBody icon={icon} label={label} description={description} />\n <span className={MENU_LOOK_CLASS.control}>{control}</span>\n </Row>\n );\n});\n\nexport interface MenuLookPanelHeaderProps extends DataAttributes {\n /** The 28px mark (an avatar, an organization mark, a colored glyph). */\n mark: React.ReactNode;\n title: React.ReactNode;\n /** One muted line under the title. */\n subtitle?: React.ReactNode | undefined;\n /** The header is a door to its own page. */\n href?: string | undefined;\n as?: LinkComponent | undefined;\n linkProps?: Record<string, unknown> | undefined;\n onClick?: React.MouseEventHandler<HTMLElement> | undefined;\n}\n\n/**\n * The row a panel opens with (Settings, the organization, the person): a 28px mark on the rows' left\n * edge, a title, an optional muted subtitle. With `href` it is a link to its page.\n */\nexport function MenuLookPanelHeader({ mark, title, subtitle, href, as, linkProps, onClick, ...data }: MenuLookPanelHeaderProps): React.ReactElement {\n const body = (\n <>\n <span className={MENU_LOOK_CLASS.headerMark}>{mark}</span>\n <span className={MENU_LOOK_CLASS.headerText}>\n <span className={MENU_LOOK_CLASS.headerTitle}>{title}</span>\n {subtitle ? <span className={MENU_LOOK_CLASS.headerSubtitle}>{subtitle}</span> : null}\n </span>\n </>\n );\n if (href) {\n const Link = as ?? \"a\";\n return (\n <Link href={href} onClick={onClick} data-menu-look-header=\"\" {...data} {...linkProps} className={MENU_LOOK_CLASS.header}>\n {body}\n </Link>\n );\n }\n return (\n <div data-menu-look-header=\"\" {...data} className={MENU_LOOK_CLASS.header}>\n {body}\n </div>\n );\n}\n\nexport interface MenuLookPanelDisclosureProps extends Pick<MenuLookRowBodyProps, \"icon\" | \"label\">, DataAttributes {\n /** Omitted with `pending`: the group's rows are still on their way. */\n children?: React.ReactNode;\n /**\n * The group's row while its rows load (a lazy chunk): the same row and chevron, inert and hidden\n * from assistive tech, so nothing below it moves when the group arrives (no layout shift).\n */\n pending?: boolean | undefined;\n defaultOpen?: boolean | undefined;\n open?: boolean | undefined;\n onOpenChange?: ((open: boolean) => void) | undefined;\n}\n\n/**\n * A folded group of rows (\"Quick Access\", \"Admin\"): a row with a down-chevron at its END that opens\n * the group in place. Closed, its rows are ABSENT (hidden: out of the hit-test tree and the tab order),\n * never clipped-but-live. Open, they sit on the same left edge as every row — no indent.\n */\nexport function MenuLookPanelDisclosure({ icon, label, children, pending, defaultOpen = false, open: openProp, onOpenChange, ...data }: MenuLookPanelDisclosureProps): React.ReactElement {\n const [ownOpen, setOwnOpen] = React.useState(defaultOpen);\n const open = openProp ?? ownOpen;\n const id = React.useId();\n const toggle = () => {\n const next = !open;\n if (openProp === undefined) setOwnOpen(next);\n onOpenChange?.(next);\n };\n if (pending) {\n return (\n <div data-menu-look-disclosure=\"\" data-pending=\"\" aria-hidden=\"true\" {...data}>\n <div className={MENU_LOOK_CLASS.item}>\n <MenuLookRowBody icon={icon} label={label} />\n <RadixChevronDownIcon className={MENU_LOOK_CLASS.chevron} aria-hidden=\"true\" data-disclosure-chevron=\"\" />\n </div>\n </div>\n );\n }\n return (\n <div data-menu-look-disclosure=\"\" {...data}>\n <button type=\"button\" className={MENU_LOOK_CLASS.item} aria-expanded={open} aria-controls={id} onClick={toggle}>\n <MenuLookRowBody icon={icon} label={label} />\n <RadixChevronDownIcon className={MENU_LOOK_CLASS.chevron} aria-hidden=\"true\" data-disclosure-chevron=\"\" />\n </button>\n <div id={id} role=\"group\" hidden={!open}>\n {children}\n </div>\n </div>\n );\n}\n\n/** A panel's section heading. */\nexport function MenuLookPanelLabel({ children, ...data }: { children: React.ReactNode } & DataAttributes): React.ReactElement {\n return (\n <div {...data} className={MENU_LOOK_CLASS.sectionLabel}>\n {children}\n </div>\n );\n}\n\n/** The line between a panel's sections. */\nexport function MenuLookPanelSeparator(): React.ReactElement {\n return <div role=\"separator\" className={MENU_LOOK_CLASS.divider} />;\n}\n\n// ── The menu's search ─────────────────────────────────────────────────────────────────────────\n\nexport interface MenuLookSearchProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"className\" | \"style\" | \"size\" | \"type\">,\n DataAttributes {}\n\n/**\n * The menu's search: its own header row (full-bleed, a hairline under it, held at the top while the\n * list scrolls) whose text starts on the rows' left edge. The host owns the value and its keys (stop\n * propagation on letters so the menu's type-ahead never takes them).\n */\nexport const MenuLookSearch = React.forwardRef<HTMLInputElement, MenuLookSearchProps>(function MenuLookSearch(\n { placeholder = \"Search\", ...props },\n ref,\n) {\n return (\n <div className={MENU_LOOK_CLASS.search} data-menu-look-search=\"\">\n <input\n ref={ref}\n type=\"search\"\n autoComplete=\"off\"\n spellCheck={false}\n placeholder={placeholder}\n aria-label={props[\"aria-label\"] ?? placeholder}\n {...props}\n />\n </div>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA4BA,YAAY,WAAW;AACvB,YAAY,2BAA2B;AACvC,YAAY,0BAA0B;AAsD7B,SAwBL,UAxBK,KA0BH,YA1BG;AA9CF,IAAM,YAAY;AAAA,EACvB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,QAAQ;AACV;AAGO,IAAM,kBAAkB;AAAA,EAC7B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,QAAQ;AACV;AAMO,SAAS,iBAAiB,EAAE,SAAS,GAAuD;AACjG,SAAO,oBAAC,UAAK,WAAW,gBAAgB,UAAW,UAAS;AAC9D;AAqBO,SAAS,gBAAgB,EAAE,MAAM,OAAO,YAAY,aAAa,OAAO,OAAO,UAAU,QAAQ,GAA6C;AACnJ,SACE,iCACG;AAAA,WAAO,oBAAC,oBAAkB,gBAAK,IAAsB;AAAA,IACtD,qBAAC,UAAK,WAAW,gBAAgB,MAC/B;AAAA,0BAAC,UAAK,WAAW,gBAAgB,OAAO,OAAO,YAAa,iBAAM;AAAA,MACjE,cAAc,oBAAC,UAAK,WAAW,gBAAgB,MAAO,uBAAY,IAAU;AAAA,OAC/E;AAAA,IACC,QAAQ,oBAAC,UAAK,WAAW,gBAAgB,OAAQ,iBAAM,IAAU;AAAA,IACjE,QAAQ,oBAAC,UAAK,WAAW,gBAAgB,OAAQ,iBAAM,IAAU;AAAA,IACjE,WAAW,oBAAC,SAAI,WAAW,gBAAgB,UAAW,oBAAS,IAAS;AAAA,IACxE,UAAU,oBAAC,kBAAe,WAAW,gBAAgB,SAAS,eAAY,QAAO,0BAAuB,IAAG,IAAK;AAAA,KACnH;AAEJ;AAGO,SAAS,kBAAkB,EAAE,aAAa,OAAO,IAAyE,CAAC,GAAW;AAC3I,SAAO,GAAG,gBAAgB,IAAI,GAAG,cAAc,IAAI,gBAAgB,MAAM,KAAK,EAAE,GAAG,SAAS,IAAI,gBAAgB,MAAM,KAAK,EAAE;AAC/H;AAgCA,SAAS,iBAAiB,EAAE,OAAO,SAAS,GAAqE;AAC/G,QAAM,OAAO,cAAc;AAC3B,QAAM,WAAiB,aAA8B,IAAI;AACzD,QAAM,cAAoB;AAAA,IACxB,CAAC,SAAgC;AAC/B,eAAS,UAAU;AACnB,WAAK,IAAI,IAAI;AAAA,IACf;AAAA,IACA,CAAC,KAAK,GAAG;AAAA,EACX;AACA,SACE,iCACE;AAAA,wBAAC,SAAI,KAAK,aAAa,WAAU,eAAc,aAAU,sBACtD,UACH;AAAA,IACC,KAAK,MAAM,SACV;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,aAAU;AAAA,QAEV,UAAU;AAAA,QACV,eAAY;AAAA,QAEZ,eAAe,CAAC,UAAU,MAAM,eAAe;AAAA,QAC/C,SAAS,MAAM,SAAS,SAAS,SAAS,EAAE,KAAK,SAAS,QAAQ,cAAc,UAAU,SAAS,CAAC;AAAA,QAEpG;AAAA,8BAAC,wBAAqB,eAAY,QAAO;AAAA,UACxC;AAAA;AAAA;AAAA,IACH,IACE;AAAA,KACN;AAEJ;AAGO,IAAM,kBAAwB,iBAAiD,SAASA,iBAC7F,EAAE,OAAO,YAAY,UAAU,eAAe,gBAAgB,UAAU,GAAG,MAAM,GACjF,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,kBAAe;AAAA,MACf,oBAAiB;AAAA,MACjB,aAAW;AAAA,MACX,gBAAc;AAAA,MACb,GAAI,iBAAiB,EAAE,iBAAiB,WAAW,IAAI,CAAC;AAAA,MACxD,GAAG;AAAA,MACJ,WAAW,gBAAgB;AAAA,MAE1B,2BAAiB,oBAAC,oBAAiB,OAAO,gBAAiB,UAAS,IAAsB;AAAA;AAAA,EAC7F;AAEJ,CAAC;AASM,IAAM,qBAA2B,iBAAoD,SAASC,oBACnG,EAAE,OAAO,YAAY,UAAU,eAAe,MAAM,QAAQ,GAAG,MAAM,GACrE,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,kBAAe;AAAA,MACf,oBAAiB;AAAA,MACjB,aAAW;AAAA,MACX,gBAAc;AAAA,MACd,YAAU;AAAA,MACT,GAAG;AAAA,MACJ,WAAW,gBAAgB;AAAA;AAAA,EAC7B;AAEJ,CAAC;AAOM,IAAM,yBAA+B,iBAAwD,SAASC,wBAC3G,EAAE,OAAO,YAAY,UAAU,eAAe,GAAG,MAAM,GACvD,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,kBAAe;AAAA,MACf,oBAAiB;AAAA,MACjB,aAAW;AAAA,MACX,gBAAc;AAAA,MACb,GAAG;AAAA,MACJ,WAAW,gBAAgB;AAAA;AAAA,EAC7B;AAEJ,CAAC;AASM,IAAM,4BAAkC,iBAA2D,SAASC,2BACjH,EAAE,OAAO,YAAY,UAAU,eAAe,MAAM,QAAQ,GAAG,MAAM,GACrE,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,kBAAe;AAAA,MACf,oBAAiB;AAAA,MACjB,aAAW;AAAA,MACX,gBAAc;AAAA,MACd,YAAU;AAAA,MACT,GAAG;AAAA,MACJ,WAAW,gBAAgB;AAAA;AAAA,EAC7B;AAEJ,CAAC;AAgDD,SAAS,aAAa,GAAmB,QAA0C;AAEjF,QAAM,OAAa,iBAA8C,SAASC,cACxE,EAAE,MAAM,OAAO,YAAY,aAAa,OAAO,OAAO,UAAU,SAAS,aAAa,QAAQ,MAAM,QAAQ,WAAW,GAAG,MAAM,GAChI,KACA;AACA,UAAM,YAAY,kBAAkB,EAAE,aAAa,OAAO,CAAC;AAC3D,UAAM,OAAO,oBAAC,mBAAgB,MAAY,OAAc,YAAwB,aAA0B,OAAc,OAAc,UAAoB,SAAkB;AAC5K,UAAM,OAAO,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;AACjD,QAAI,MAAM;AACR,aACE,oBAAC,EAAE,MAAF,EAAO,KAAU,SAAO,MAAC,aAAW,GAAG,MAAM,SAAU,GAAG,OAAQ,GAAG,MAAM,WAC1E,8BAAC,OAAE,MAAY,QAAgB,KAAK,WAAW,WAAW,wBAAwB,QAAY,GAAG,WAC9F,gBACH,GACF;AAAA,IAEJ;AACA,WACE,oBAAC,EAAE,MAAF,EAAO,KAAU,aAAW,GAAG,MAAM,SAAU,GAAG,OAAQ,GAAG,MAAM,WACjE,gBACH;AAAA,EAEJ,CAAC;AAOD,QAAM,aAAmB,iBAAoD,SAASC,oBACpF,EAAE,MAAM,OAAO,YAAY,aAAa,OAAO,OAAO,UAAU,SAAS,GAAG,MAAM,GAClF,KACA;AACA,WACE,qBAAC,EAAE,YAAF,EAAa,KAAU,aAAW,GAAG,MAAM,gBAAiB,GAAG,OAAQ,GAAI,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC,GAAI,WAAW,gBAAgB,MAC7I;AAAA,0BAAC,mBAAgB,MAAY,OAAc,YAAwB,aAA0B,OAAc,OAAc,UAAoB;AAAA,MAC7I,oBAAC,yBAAsB,WAAW,gBAAgB,SAAS,eAAY,QAAO;AAAA,OAChF;AAAA,EAEJ,CAAC;AAID,QAAM,eAAqB,iBAAsD,SAASC,sBACxF,EAAE,MAAM,OAAO,YAAY,aAAa,OAAO,OAAO,UAAU,SAAS,GAAG,MAAM,GAClF,KACA;AACA,UAAM,KAAK,YAAY;AACvB,WACE,oBAAC,EAAE,cAAF,EAAe,KAAW,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,QAAQ,GAAK,GAAG,OAAO,WAAW,gBAAgB,MAC9G,8BAAC,mBAAgB,MAAM,KAAK,oBAAC,kBAAe,WAAW,gBAAgB,MAAM,IAAM,QAAQ,oBAAC,UAAK,WAAW,gBAAgB,MAAM,eAAY,QAAO,GAAK,OAAc,YAAwB,aAA0B,OAAc,OAAc,UAAoB,GAC5Q;AAAA,EAEJ,CAAC;AAID,QAAM,YAAkB,iBAAmD,SAASC,mBAClF,EAAE,MAAM,OAAO,YAAY,aAAa,OAAO,OAAO,UAAU,GAAG,MAAM,GACzE,KACA;AACA,WACE,qBAAC,EAAE,WAAF,EAAY,KAAW,GAAG,OAAO,WAAW,gBAAgB,MAC3D;AAAA,0BAAC,mBAAgB,MAAY,OAAc,YAAwB,aAA0B,OAAc,OAAc,UAAoB;AAAA,MAC7I,oBAAC,EAAE,eAAF,EAAgB,WAAW,gBAAgB,SAAS,0BAAuB,IAC1E,8BAAC,kBAAe,eAAY,QAAO,GACrC;AAAA,OACF;AAAA,EAEJ,CAAC;AAGD,QAAM,QAAc,iBAA+C,SAASC,eAC1E,EAAE,aAAa,UAAU,GAAG,MAAM,GAClC,KACA;AACA,QAAI,CAAC,YAAa,QAAO,oBAAC,EAAE,OAAF,EAAQ,KAAW,GAAG,OAAO,WAAW,gBAAgB,cAAe,UAAS;AAC1G,WACE,qBAAC,EAAE,OAAF,EAAQ,KAAW,GAAG,OAAO,iBAAc,IAAG,WAAW,gBAAgB,cACxE;AAAA,0BAAC,UAAM,UAAS;AAAA,MAChB,oBAAC,UAAK,WAAW,gBAAgB,MAAO,uBAAY;AAAA,OACtD;AAAA,EAEJ,CAAC;AAGD,QAAM,YAAkB,iBAA2C,SAASC,mBAAkB,OAAO,KAAK;AACxG,WAAO,oBAAC,EAAE,WAAF,EAAY,KAAW,GAAG,OAAO,WAAW,gBAAgB,SAAS;AAAA,EAC/E,CAAC;AAED,SAAO,EAAE,MAAM,YAAY,cAAc,WAAW,OAAO,UAAU;AACvE;AAEA,IAAM,eAAe,aAAa,uBAAuB,eAAe;AACxE,IAAM,cAAc,aAAa,sBAAmD,cAAc;AAE3F,IAAM,eAAe,aAAa;AAElC,IAAM,cAAoC;AAC1C,IAAM,qBAAqB,aAAa;AACxC,IAAM,uBAAuB,aAAa;AAE1C,IAAM,qBAA2C;AACjD,IAAM,oBAAoB,aAAa;AACvC,IAAM,gBAAgB,aAAa;AACnC,IAAM,oBAAoB,aAAa;AAGvC,IAAM,sBAAsB,YAAY;AACxC,IAAM,qBAA0C;AAChD,IAAM,4BAA4B,YAAY;AAC9C,IAAM,8BAA8B,YAAY;AAChD,IAAM,4BAAiD;AACvD,IAAM,2BAA2B,YAAY;AAC7C,IAAM,uBAAuB,YAAY;AACzC,IAAM,2BAA2B,YAAY;AAwB7C,IAAM,gBAAsB,iBAA+C,SAASC,eACzF,EAAE,OAAO,YAAY,UAAU,eAAe,UAAU,YAAY,WAAW,OAAO,QAAQ,GAAG,MAAM,GACvG,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,kBAAe;AAAA,MACf,oBAAiB;AAAA,MACjB,gBAAc;AAAA,MACb,GAAI,YAAY,EAAE,mBAAmB,UAAU,IAAI,CAAC;AAAA,MACrD,aAAW;AAAA,MACX,gBAAc;AAAA,MACb,GAAG;AAAA,MACJ,WAAW,gBAAgB;AAAA;AAAA,EAC7B;AAEJ,CAAC;AAUM,IAAM,yBAA+B,iBAAwD,SAASC,wBAC3G,EAAE,OAAO,YAAY,UAAU,eAAe,OAAO,QAAQ,GAAG,MAAM,GACtE,KACA;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,UAAQ;AAAA,MACR,kBAAe;AAAA,MACf,oBAAiB;AAAA,MACjB,mBAAgB;AAAA,MAChB,gBAAa;AAAA,MACb,aAAW;AAAA,MACX,gBAAc;AAAA,MACb,GAAG;AAAA,MACJ,WAAW,gBAAgB;AAAA;AAAA,EAC7B;AAEJ,CAAC;AA+BM,IAAM,oBAA0B,iBAAgD,SAASC,mBAC9F,EAAE,MAAM,OAAO,YAAY,aAAa,OAAO,OAAO,UAAU,SAAS,SAAS,aAAa,QAAQ,MAAM,QAAQ,KAAK,IAAI,WAAW,SAAS,OAAO,YAAY,GAAG,MAAM,GAC9K,KACA;AACA,QAAM,SAAS,QAAQ,WAAW,OAAO;AACzC,QAAM,OAAO,oBAAC,mBAAgB,MAAY,OAAc,YAAwB,aAA0B,OAAc,OAAc,UAAoB,SAAS,QAAQ;AAC3K,QAAM,YAAY,kBAAkB,EAAE,aAAa,OAAO,CAAC;AAC3D,QAAM,OAAO,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;AAChD,MAAI,MAAM;AACR,UAAM,OAAO,MAAM;AACnB,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK,QAAQ,WAAW,WAAW,wBAAwB;AAAA,QAC3D;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACJ;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,EAEJ;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,gBAAgB,QAAQ;AAAA,MAC3D,GAAG;AAAA,MACH,GAAG;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ,CAAC;AAiBM,IAAM,0BAAgC,iBAAsD,SAASC,yBAC1G,EAAE,MAAM,OAAO,aAAa,SAAS,KAAK,OAAO,GAAG,MAAM,GAC1D,KACA;AACA,QAAM,MAAM;AACZ,SACE,qBAAC,OAAI,KAA8B,oBAAiB,IAAI,GAAG,OAAO,WAAW,gBAAgB,MAC3F;AAAA,wBAAC,mBAAgB,MAAY,OAAc,aAA0B;AAAA,IACrE,oBAAC,UAAK,WAAW,gBAAgB,SAAU,mBAAQ;AAAA,KACrD;AAEJ,CAAC;AAmBM,SAAS,oBAAoB,EAAE,MAAM,OAAO,UAAU,MAAM,IAAI,WAAW,SAAS,GAAG,KAAK,GAAiD;AAClJ,QAAM,OACJ,iCACE;AAAA,wBAAC,UAAK,WAAW,gBAAgB,YAAa,gBAAK;AAAA,IACnD,qBAAC,UAAK,WAAW,gBAAgB,YAC/B;AAAA,0BAAC,UAAK,WAAW,gBAAgB,aAAc,iBAAM;AAAA,MACpD,WAAW,oBAAC,UAAK,WAAW,gBAAgB,gBAAiB,oBAAS,IAAU;AAAA,OACnF;AAAA,KACF;AAEF,MAAI,MAAM;AACR,UAAM,OAAO,MAAM;AACnB,WACE,oBAAC,QAAK,MAAY,SAAkB,yBAAsB,IAAI,GAAG,MAAO,GAAG,WAAW,WAAW,gBAAgB,QAC9G,gBACH;AAAA,EAEJ;AACA,SACE,oBAAC,SAAI,yBAAsB,IAAI,GAAG,MAAM,WAAW,gBAAgB,QAChE,gBACH;AAEJ;AAoBO,SAAS,wBAAwB,EAAE,MAAM,OAAO,UAAU,SAAS,cAAc,OAAO,MAAM,UAAU,cAAc,GAAG,KAAK,GAAqD;AACxL,QAAM,CAAC,SAAS,UAAU,IAAU,eAAS,WAAW;AACxD,QAAM,OAAO,YAAY;AACzB,QAAM,KAAW,YAAM;AACvB,QAAM,SAAS,MAAM;AACnB,UAAM,OAAO,CAAC;AACd,QAAI,aAAa,OAAW,YAAW,IAAI;AAC3C,mBAAe,IAAI;AAAA,EACrB;AACA,MAAI,SAAS;AACX,WACE,oBAAC,SAAI,6BAA0B,IAAG,gBAAa,IAAG,eAAY,QAAQ,GAAG,MACvE,+BAAC,SAAI,WAAW,gBAAgB,MAC9B;AAAA,0BAAC,mBAAgB,MAAY,OAAc;AAAA,MAC3C,oBAAC,wBAAqB,WAAW,gBAAgB,SAAS,eAAY,QAAO,2BAAwB,IAAG;AAAA,OAC1G,GACF;AAAA,EAEJ;AACA,SACE,qBAAC,SAAI,6BAA0B,IAAI,GAAG,MACpC;AAAA,yBAAC,YAAO,MAAK,UAAS,WAAW,gBAAgB,MAAM,iBAAe,MAAM,iBAAe,IAAI,SAAS,QACtG;AAAA,0BAAC,mBAAgB,MAAY,OAAc;AAAA,MAC3C,oBAAC,wBAAqB,WAAW,gBAAgB,SAAS,eAAY,QAAO,2BAAwB,IAAG;AAAA,OAC1G;AAAA,IACA,oBAAC,SAAI,IAAQ,MAAK,SAAQ,QAAQ,CAAC,MAChC,UACH;AAAA,KACF;AAEJ;AAGO,SAAS,mBAAmB,EAAE,UAAU,GAAG,KAAK,GAAuE;AAC5H,SACE,oBAAC,SAAK,GAAG,MAAM,WAAW,gBAAgB,cACvC,UACH;AAEJ;AAGO,SAAS,yBAA6C;AAC3D,SAAO,oBAAC,SAAI,MAAK,aAAY,WAAW,gBAAgB,SAAS;AACnE;AAaO,IAAM,iBAAuB,iBAAkD,SAASC,gBAC7F,EAAE,cAAc,UAAU,GAAG,MAAM,GACnC,KACA;AACA,SACE,oBAAC,SAAI,WAAW,gBAAgB,QAAQ,yBAAsB,IAC5D;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,cAAa;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,MACA,cAAY,MAAM,YAAY,KAAK;AAAA,MAClC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ,CAAC;","names":["MenuLookContent","MenuLookSubContent","MenuLookContextContent","MenuLookContextSubContent","MenuLookItem","MenuLookSubTrigger","MenuLookCheckboxItem","MenuLookRadioItem","MenuLookLabel","MenuLookSeparator","MenuLookPanel","MenuLookPopoverContent","MenuLookPanelItem","MenuLookPanelControlRow","MenuLookSearch"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/confirm-host.tsx","../src/archived-disclosure.tsx","../src/organization-picker.tsx","../src/app-shell/status-dot.tsx","../src/app-shell/app-rail.tsx","../src/resizable.tsx","../src/app-shell/canvas.tsx","../src/app-shell/mode-switch.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * `<ConfirmDialogHost />` — render ONCE, near the root of every provider tree,\n * so the imperative `confirm()` always has a live host to dispatch to.\n *\n * THE SPLIT (census row 19i, 2026-09-07). The confirm system is two halves in\n * two packages, on purpose:\n *\n * `@ai-matrx/kit/confirm-opener` the OPENER — `confirm()`, the host\n * registry, the request queue. Pure TS: zero\n * React, zero markup, zero CSS. Statically\n * importable from a Redux thunk, a util, a\n * sync handler — hundreds of call sites at\n * near-zero bundle cost.\n * `@ai-matrx/design-system` the BODY — this host and `ConfirmDialog`,\n * built on the package AlertDialog so the\n * surface gets the shipped motion layer and\n * the themed scrim instead of the host-plugin\n * classes and the hardcoded black scrim\n * kit could neither style nor animate.\n *\n * Design-system depends on kit, so this direction is the acyclic one; kit\n * re-exports nothing of the body. A consumer mounts `<ConfirmDialogHost />`\n * from here and calls `confirm()` from there — the two find each other through\n * the opener's `Symbol.for(\"ai-matrx.kit.confirm-opener-state\")` globalThis\n * slot, which is deliberately NOT a module-level variable: with unsplit dual\n * ESM/CJS bundles each loader graph instantiates its own module, and a module\n * local would silently split host registration from callers. Never \"clean that\n * up\".\n *\n * Pre-mount `confirm()` calls queue inside the opener and resolve as soon as\n * this host registers — a destructive action triggered in the first ~50ms after\n * load still gets a real confirmation, never a silent default-yes/no.\n *\n * NO FRAMEWORK IMPORT. The matrx-frontend original split shell + impl and\n * loaded the impl through `next/dynamic({ ssr: false })` to keep radix out of\n * route entry chunks. A framework-agnostic package cannot do that, so this is\n * ONE directly-imported component; hosts that want the code-splitting lazy-load\n * it themselves:\n * `dynamic(() => import(\"@ai-matrx/design-system\").then(m => m.ConfirmDialogHost), { ssr: false })`\n * The \"render `<ConfirmDialogHost/>` once\" contract is unchanged either way.\n *\n * Imperative model: calls to `confirm(...)` push a request into the opener's\n * queue; `useOpenerHost` (`@ai-matrx/kit/opener-react`) drains it one at a time\n * and this component renders a `<ConfirmDialog>` for the active request. The promise resolves `true` on Confirm, `false` on\n * cancel/dismiss. The dialog closes immediately on click — callers that need an\n * in-dialog busy spinner during async work use the inline `<ConfirmDialog>`\n * with the `busy` prop instead.\n */\n\nimport { confirmOpener } from \"@ai-matrx/kit/confirm-opener\";\nimport { useOpenerHost } from \"@ai-matrx/kit/opener-react\";\nimport * as React from \"react\";\n\nimport { ConfirmDialog } from \"./confirm-dialog\";\n\nexport function ConfirmDialogHost() {\n // The registration, the ref-backed queue, the drain effect and the\n // settle-once callback are ALL `useOpenerHost` (kit 0.10.0). They used to be\n // written out here — and identically in three matrx-frontend dialog hosts,\n // which is exactly the duplication the opener primitive ends. What is left\n // below is the only part that was ever this package's: the dialog body.\n // `shown`, not `request`: the dialog animates out AFTER it is answered, and\n // `request` is already null by then — the body used to fade out empty\n // (reviewer, 2026-10-02). `shown` keeps the answered words until the next\n // question replaces them.\n const { shown, open, settle } = useOpenerHost(confirmOpener);\n\n // `ready` (kit 0.22.0): Confirm is held until the question can say what it\n // will do. Settling either way releases it — a failed read never traps the\n // person. Keyed by the request object, so the next question starts held.\n const [readyFor, setReadyFor] = React.useState<object | null>(null);\n const ready = shown?.ready;\n React.useEffect(() => {\n if (!shown || !ready) return undefined;\n let live = true;\n const release = () => {\n if (live) setReadyFor(shown);\n };\n Promise.resolve(ready).then(release, release);\n return () => {\n live = false;\n };\n }, [shown, ready]);\n const held = !!ready && readyFor !== shown;\n\n const handleConfirm = React.useCallback(() => settle(true), [settle]);\n const handleOpenChange = React.useCallback(\n (next: boolean) => {\n // Any dismiss (Esc / backdrop / Cancel) is a \"no\" — never a silent yes.\n if (!next) settle(false);\n },\n [settle],\n );\n\n return (\n <ConfirmDialog\n open={open}\n onOpenChange={handleOpenChange}\n title={shown?.title ?? \"\"}\n description={shown?.description}\n confirmLabel={shown?.confirmLabel}\n cancelLabel={shown?.cancelLabel}\n variant={shown?.variant}\n confirmHeld={held}\n onConfirm={handleConfirm}\n />\n );\n}\n","\"use client\";\n\n/**\n * ArchivedDisclosure — THE ARCHIVED-ITEMS LAW, card-list half.\n * (`common-docs/policies/archived-items.md`, Arman 2026-09-09.)\n *\n * Every list over an entity that can be archived carries an archive control,\n * it defaults to HIDING archived rows, and revealing them is one or two\n * clicks — on the surface itself. There are exactly TWO implementations of\n * that control in the platform, and both live in THIS package:\n *\n * • `ArchiveFilter` — the tri-state segmented control (Active only /\n * Archived only / Active + archived) for table and browse surfaces whose\n * reader takes an archive parameter. Prefer it whenever the surface can\n * express the request server-side.\n * • `ArchivedDisclosure` — THIS component: a one-click \"Archived (N)\"\n * disclosure, closed by default, revealing the archived rows in place\n * underneath. For card lists, panels and pickers that are not table\n * shaped.\n *\n * Never invent a third. The disclosure was proven first in matrx-frontend's\n * Transcript Studio, lived as `components/official/ArchivedDisclosure` there,\n * and moved here (0.14.0) verbatim so every client inherits the same control\n * instead of re-growing it per app.\n *\n * Both controls share one vocabulary: `ARCHIVE_LABEL` is the single noun, and\n * `archiveFilterFromDisclosure(open)` says a disclosure's state in the\n * tri-state words for a host whose toggle IS a server request.\n *\n * Two shapes, one primitive:\n *\n * <ArchivedDisclosure count={n} open={open} onOpenChange={setOpen}>\n * …archived rows…\n * </ArchivedDisclosure>\n *\n * renders the button AND the revealed block. Omit `children` when the caller\n * merges the archived rows into an existing table/grid itself — the button is\n * then the whole control.\n *\n * The count is ALWAYS the true number of archived rows the surface holds. A\n * screen never lies: when there is nothing archived the control renders\n * nothing at all rather than an empty promise. A surface whose archive view is\n * a SERVER request (the rows below the button are the archived page itself,\n * not children of it) passes `keepWhileOpen` so the revealed view never loses\n * its way back.\n *\n * `countLabel` exists for the one case a bare integer cannot tell the truth: a\n * server-side count that hit its cap (render `\"12+\"`), or a count that has not\n * landed yet (pass `null` and no parenthetical is printed at all).\n */\n\nimport * as React from \"react\";\n\nimport { ARCHIVE_LABEL } from \"./archive-filter\";\nimport { cn } from \"./cn\";\nimport { ArchiveIcon, ChevronDownIcon, ChevronRightIcon } from \"./icons\";\n\n/** What every archive on this platform promises, said once (the noun voice opens with it). */\nexport const ARCHIVED_NEVER_DESTROYED =\n \"Archiving never destroys anything. What you put away waits here until somebody brings it back.\";\n\nexport interface ArchivedDisclosureProps {\n /**\n * True number of archived rows this surface holds. 0 renders nothing. Absent = not read yet:\n * the control still draws (a count nobody has read is not a reason to hide the way in) and no\n * parenthetical is printed — a \"(0)\" the screen guessed would be a lie.\n */\n count?: number | undefined;\n /** Whether archived rows are revealed (controlled). Omit to let the control hold it itself. */\n open?: boolean | undefined;\n /** Uncontrolled only: open on first render (the address asked for the archive). */\n defaultOpen?: boolean | undefined;\n onOpenChange?: ((open: boolean) => void) | undefined;\n /**\n * The archived rows. Omit when the host merges them into its own list and\n * only needs the toggle.\n */\n children?: React.ReactNode;\n /** Noun for the rows, so the button reads in the surface's own words. */\n label?: string;\n /**\n * THE NOUN VOICE: the archived things in the plural (\"portals\", \"pick lists\"). The button then\n * says \"Show archived portals (3)\" / \"Hide archived portals\", and the revealed block opens with\n * {@link ARCHIVED_NEVER_DESTROYED} (override with `note`). Takes precedence over `label`.\n */\n noun?: string | undefined;\n /** A line at the top of the revealed block. `null` = none. Default: the noun voice's promise, else none. */\n note?: React.ReactNode;\n /**\n * Override the parenthetical. A string replaces the number (`\"12+\"` for a\n * capped server count); `null` prints no parenthetical at all, for a count\n * that has not arrived yet. Omit it and the honest `count` is printed.\n */\n countLabel?: string | null;\n /**\n * Keep the control rendered while `open` even at `count === 0`. For surfaces\n * where opening SWITCHES the list to the archive (a server-side filter)\n * rather than nesting rows inside this component: without it the way back\n * would vanish the moment the count read zero or had not landed.\n */\n keepWhileOpen?: boolean;\n /**\n * Draw the way in even when the count reads 0 — the revealed block then says the archive is\n * empty in its own words (a rail whose archive is a sentence, never a blank). Default: on in\n * the noun voice, off otherwise. A 0 is never printed as \"(0)\" in the noun voice.\n */\n showWhenEmpty?: boolean;\n className?: string | undefined;\n contentClassName?: string;\n}\n\nexport function ArchivedDisclosure({\n count,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n label = ARCHIVE_LABEL,\n noun,\n note,\n countLabel,\n keepWhileOpen = false,\n showWhenEmpty,\n className,\n contentClassName,\n}: ArchivedDisclosureProps) {\n const [ownOpen, setOwnOpen] = React.useState(defaultOpen);\n const open = openProp ?? ownOpen;\n // Nothing archived: an empty promise, so render nothing — unless this\n // surface's open state IS the archive view, whose way back must never vanish.\n const drawEmpty = showWhenEmpty ?? noun !== undefined;\n if (count !== undefined && count <= 0 && !drawEmpty && !(open && keepWhileOpen)) return null;\n const toggle = () => {\n const next = !open;\n if (openProp === undefined) setOwnOpen(next);\n onOpenChange?.(next);\n };\n const parenthetical =\n countLabel !== undefined ? countLabel : count === undefined || (noun !== undefined && count <= 0) ? null : String(count);\n const words = noun ? `${open ? \"Hide\" : \"Show\"} archived ${noun}` : label;\n const shownNote = note !== undefined ? note : noun ? ARCHIVED_NEVER_DESTROYED : null;\n return (\n <div className={cn(\"min-w-0\", className)} data-slot=\"archived-disclosure\">\n <button\n type=\"button\"\n onClick={toggle}\n aria-expanded={open}\n data-slot=\"archived-disclosure-toggle\"\n className=\"flex w-full items-center gap-2 rounded-lg px-2 py-2 text-sm text-muted-foreground hover:bg-accent active:bg-accent\"\n >\n {open ? (\n <ChevronDownIcon className=\"h-4 w-4 shrink-0\" />\n ) : (\n <ChevronRightIcon className=\"h-4 w-4 shrink-0\" />\n )}\n <ArchiveIcon className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate\">\n {parenthetical === null ? words : `${words} (${parenthetical})`}\n </span>\n </button>\n {open && (children || shownNote) ? (\n <div className={cn(\"mt-1\", contentClassName)}>\n {shownNote ? <p className=\"px-2 pb-2 text-xs text-muted-foreground\">{shownNote}</p> : null}\n {children}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default ArchivedDisclosure;\n","\"use client\";\n\n/**\n * OrganizationPicker — THE ONE \"which organization am I acting in\" control,\n * identical on every Matrx surface (the main app's user menu and header nudge,\n * Workflow Studio's sidebar, the admin dashboard's settings).\n *\n * Ported from matrx-frontend `features/organizations/components/\n * OrganizationPickerPanel.tsx` + `UserMenuOrgSection.tsx` + `DefaultOrgSwitch.tsx`\n * (2026-09-08), which until then were the ONLY surfaces with the full picker;\n * Studio and the dashboard each had a bare `<Select>` with different copy,\n * different placement and no default control. Three UIs for one fact.\n *\n * THE ACTIVE ROW IS THE ANSWER (owner, 2026-10-01). The active organization is\n * the highlighted row — tinted, bold, ringed and checked — and nothing else:\n * the \"Working in …\" sentence above the list is gone (\"It should be\n * highlighted and clear\"), and so is the \"Keep it at the top\" switch.\n *\n * FAVORITES (owner, 2026-10-01: \"add a star you can click to favorite any of\n * them\"). Every row carries its own star; a person favorites as many as they\n * like, and favorites are drawn first. The star never selects the row — it is\n * a sibling button, not part of the row — and it picks no organization for\n * anyone: which organization you are working in is this device's own\n * remembered choice (the host's resolver), never a star.\n *\n * 🚨 A HUNDRED ROWS IS NOT A LIST (VERIFIER-8 MEDIUM-3, 2026-09-21).\n * The first screen of the data product offered the admin account's 116\n * organizations nine at a time, with no search, most of them lane fixtures.\n * Three things answer that, and all three are here rather than in one host:\n * • SEARCH over name and abbreviation, once the list passes eight rows.\n * • TEST ORGANIZATIONS HIDDEN by default behind the platform's one\n * archive-style disclosure (`ArchivedDisclosure`), with their count always\n * on screen. Hidden, never dropped.\n * • THE PERSON'S OWN organizations drawn first, under the starred one.\n * The host classifies (`isTestFixture`, `isOwn`); this component decides\n * nothing about a name it is given.\n *\n * Seam inversions from the origin: lucide `Check`/`Star` become package\n * SVGs (C19); the host `Switch` becomes this package's; `cn` is local.\n */\n\nimport * as React from \"react\";\n\nimport { ArchivedDisclosure } from \"./archived-disclosure\";\nimport { cn } from \"./cn\";\nimport { ErrorBox } from \"./error-box\";\nimport { CheckIcon, StarIcon } from \"./icons\";\nimport { Input } from \"./input\";\nimport { Skeleton } from \"./skeleton\";\nimport { Button } from \"./controls/controls\";\nimport { MENU_LOOK_CLASS, MenuLookRowBody } from \"./menu-look\";\n\n/**\n * Above this many rows the list stops being something a person reads and\n * starts being something they hunt through, so the search box appears. Below\n * it a search box is one more control over a list the eye already took in.\n */\nconst SEARCH_APPEARS_ABOVE = 8;\n\n/**\n * Case-insensitive substring over the two things a person actually types. Exported once: every\n * organization picker (this one, the desktop sheet) searches the same way.\n */\nexport function matchesOrganizationQuery(org: Pick<OrganizationPickerOrganization, \"name\" | \"abbreviation\">, query: string): boolean {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n if (org.name.toLowerCase().includes(q)) return true;\n const abbreviation = org.abbreviation?.trim().toLowerCase();\n return !!abbreviation && abbreviation.includes(q);\n}\n\nexport interface OrganizationPickerOrganization {\n id: string;\n name: string;\n /** Database-validated 2–3 uppercase letters. Optional — not every report carries it. */\n abbreviation?: string | null;\n /**\n * THE ADDRESS, for when the NAME is not enough — its slug, or whatever else the\n * host has that tells two of them apart.\n *\n * 🚨 WHY (crew D2, 2026-09-21). Two organizations called \"Kessler Lab for Applied\n * Microbial Ecology\" and two called \"Wraithmoor Regional Museum of Art & Craft\" sat\n * in one list, identical down to the abbreviation tile, and a person had no way of\n * knowing which one they were about to work in. The list drew the name and nothing\n * else, so there was nothing for it to draw.\n *\n * It is shown ONLY on the rows whose name another row in the list also carries —\n * the way Slack shows a workspace's URL and Google shows the account's email, and\n * only where it settles the question. A list of distinct names stays exactly as it\n * was, because a second line under every row is noise a person learns to skip.\n */\n distinguisher?: string | null;\n /**\n * This organization is a TEST FIXTURE — a lane's scratch organization, not a\n * business anybody works in. Classified in `iam.organizations.settings`\n * (`test_fixture`), never guessed from its name.\n *\n * 🚨 WHY (VERIFIER-8 MEDIUM-3, 2026-09-21). The admin account belongs to 116\n * organizations and 59 of them are fixtures. The first screen of the data\n * product offered all of them, nine at a time, with no search — so the two\n * or three a person actually works in were buried under lane debris. The\n * archived-items law already answers this shape everywhere else in the\n * platform: hide by default, ONE disclosure to reveal, and the count of what\n * is hidden is always on screen. It is hidden, never dropped: a fixture the\n * person genuinely wants is one click away.\n */\n isTestFixture?: boolean;\n /**\n * The signed-in person created this organization. Drawn before the rest,\n * under the starred one — the same reason Slack puts your own workspace\n * first: in a list of a hundred, yours must not be something you search for.\n */\n isOwn?: boolean;\n /**\n * A short trailing label for the row — what a click does or the row's state\n * (\"Open\", \"Finish setup\", \"Turn on HR\"). Muted text, right-aligned; the row\n * stays one button. Omitted, the row is exactly as before.\n */\n detail?: string | null;\n /**\n * Fold this row behind the host's second disclosure (`foldedLabel`) — for rows\n * the person rarely came for (organizations without HR). Hidden, counted,\n * one click away; a search that matches only folded rows opens the fold.\n */\n folded?: boolean;\n}\n\n/**\n * THE LIST IS A PAGE (bounded organizations, 2026-10-16). A person in hundreds of organizations\n * (an agency with a client organization each) is never sent all of them: the host passes the\n * first page and this. The box then always shows; every keystroke goes to `onQueryChange` and the\n * host answers with the matching rows from its FULL list (server-side), which are drawn as given —\n * no second local filter. \"Show more\" appears while `hasMore`.\n */\nexport interface OrganizationPickerMore {\n onQueryChange: (query: string) => void;\n /** More rows exist past these, for the current query. */\n hasMore: boolean;\n onLoadMore: () => void;\n loadingMore?: boolean;\n /** How many the person has in all, for the current query. */\n total?: number;\n}\n\nexport interface OrganizationPickerProps {\n organizations: readonly OrganizationPickerOrganization[];\n /** The list is the first page of a longer one; omit when it is the whole list. */\n more?: OrganizationPickerMore;\n /** The organization the person is acting in right now; null = nothing chosen. */\n activeOrganizationId: string | null;\n /** The person's favorite organizations, drawn first and starred. */\n favoriteOrganizationIds?: readonly string[];\n loading?: boolean;\n /** Memberships could not be read. The panel says so instead of showing an empty list. */\n loadFailed?: boolean;\n /** Choose the active organization. Hosts persist + refetch here. */\n onSelect: (organization: OrganizationPickerOrganization) => void;\n /**\n * Favorite (true) or unfavorite (false) one organization. Omit to draw no\n * star buttons — a host with no write path must not show a control that\n * does nothing (a favorite is still marked, read-only).\n */\n onToggleFavorite?: ((organizationId: string, favorite: boolean) => void) | undefined;\n /** Hide the \"Organization\" eyebrow when the host already labels the section. */\n hideHeading?: boolean;\n /**\n * `\"menu\"`: the rows are the one menu look's rows (`cm-item`: a 16px mark in the icon slot, the name,\n * the active one marked by a check at its END) — the picker inside a menu-look panel (the account\n * rail's organization menu). Default: the picker's own rows.\n */\n look?: \"default\" | \"menu\";\n /** The noun on the disclosure that holds `folded` rows. Default \"More\". */\n foldedLabel?: string;\n className?: string;\n}\n\n/**\n * An organization's color — one of a fixed set of hues, chosen from its id so\n * the same organization wears the same color on every surface and every\n * device. Color tells organizations apart at a glance; the letters still say\n * which one (owner, 2026-10-01: \"a bit of color for the logos\").\n */\nconst ORGANIZATION_HUES = [217, 262, 330, 12, 32, 152, 189, 290] as const;\nexport function organizationColor(seed: string): { background: string; color: string } {\n let hash = 0;\n for (let index = 0; index < seed.length; index += 1) {\n hash = (hash * 31 + seed.charCodeAt(index)) >>> 0;\n }\n const hue = ORGANIZATION_HUES[hash % ORGANIZATION_HUES.length];\n return { background: `hsl(${hue} 62% 46%)`, color: \"#fff\" };\n}\n\n/**\n * THE organization mark — its own logo when it has one, otherwise its 2–3\n * letter abbreviation on its color tile (the first letter of the name when the\n * report has no abbreviation, so a tile is never empty). Three letters get a\n * smaller face than two so they fit the tile. Every Matrx surface draws this.\n */\nexport function OrganizationMark({\n id,\n name,\n abbreviation,\n logoUrl,\n size = 20,\n className,\n}: {\n /** Seeds the color; the name is used when absent. */\n id?: string | null | undefined;\n name: string;\n abbreviation?: string | null | undefined;\n logoUrl?: string | null | undefined;\n size?: number;\n className?: string | undefined;\n}) {\n const box = { width: size, height: size };\n if (logoUrl) {\n return (\n <span\n style={box}\n className={cn(\"relative inline-flex shrink-0 overflow-hidden rounded-md bg-muted\", className)}\n data-slot=\"organization-mark\"\n >\n <img src={logoUrl} alt={name} className=\"h-full w-full object-cover\" />\n </span>\n );\n }\n const letters = ((abbreviation && abbreviation.trim()) || name.trim().slice(0, 1) || \"?\")\n .slice(0, 3)\n .toUpperCase();\n const fontSize = Math.round(size * (letters.length >= 3 ? 0.36 : 0.44));\n return (\n <span\n style={{ ...box, ...organizationColor(id || name), fontSize }}\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-md font-bold leading-none tracking-tight\",\n className,\n )}\n aria-label={`Organization abbreviation ${letters}`}\n title={letters}\n data-slot=\"organization-mark\"\n >\n {letters}\n </span>\n );\n}\n\n/**\n * THE ORDER every organization list uses: the ACTIVE organization (where the person is working, and\n * where new things go by default), then their favorites, then their OWN organizations, then everything\n * else. Inside each band the host's order is kept exactly as given — this reorders bands, it never sorts\n * names. Exported once for every picker (this one, the desktop sheet).\n */\nexport function orderOrganizationsForPicker<T extends { id: string; isOwn?: boolean | undefined }>(\n organizations: readonly T[],\n favoriteOrganizationIds: readonly string[],\n activeOrganizationId: string | null = null,\n): T[] {\n const favorites = new Set(favoriteOrganizationIds);\n const rank = (org: T) => (org.id === activeOrganizationId ? -1 : favorites.has(org.id) ? 0 : org.isOwn ? 1 : 2);\n return [...organizations].sort((a, b) => rank(a) - rank(b));\n}\n\nexport function OrganizationPicker({\n organizations,\n activeOrganizationId,\n favoriteOrganizationIds = [],\n loading = false,\n loadFailed = false,\n onSelect,\n onToggleFavorite,\n hideHeading = false,\n look = \"default\",\n foldedLabel = \"More\",\n className,\n more,\n}: OrganizationPickerProps) {\n const [query, setQuery] = React.useState(\"\");\n const [showFixtures, setShowFixtures] = React.useState(false);\n const [showFolded, setShowFolded] = React.useState(false);\n\n const favorites = new Set(favoriteOrganizationIds);\n const isFavorite = (id: string) => favorites.has(id);\n /**\n * THE ORDER, and it is the whole point of this control on an account with a\n * hundred memberships: the person's favorites, then their OWN organizations,\n * then everything else. Inside each band the host's order is kept exactly as\n * given — this reorders bands, it never sorts names.\n */\n const ordered = orderOrganizationsForPicker(organizations, favoriteOrganizationIds, activeOrganizationId);\n\n // A paged host already answered the query from its full list; filtering again would drop its\n // slug matches.\n const matching = more ? ordered : ordered.filter((org) => matchesOrganizationQuery(org, query));\n // The ACTIVE organization is always in the main list, first: a test organization the person is working in\n // is never behind the \"Test organizations\" disclosure, and a folded one is never behind \"More\".\n const isActive = (org: OrganizationPickerOrganization) => org.id === activeOrganizationId;\n const listed = matching.filter((org) => isActive(org) || (!org.isTestFixture && !org.folded));\n const folded = matching.filter((org) => !isActive(org) && !org.isTestFixture && org.folded);\n const fixtures = matching.filter((org) => !isActive(org) && org.isTestFixture);\n // The fold opens by itself when it is all there is, or when a search found\n // something inside it — a match is never hidden behind a closed disclosure.\n const foldOpen =\n showFolded || (folded.length > 0 && (listed.length === 0 || query.trim().length > 0));\n // Same rule for the test organizations: when they are ALL the person has\n // (an account whose only workspace is a test fixture) the disclosure opens by\n // itself — a collapsed group holding the only choice reads as \"no workspace\"\n // (feedback 6717c61d: \"An organization is needed\" with the one workspace\n // hidden under \"Test organizations (n)\").\n const fixturesOpen =\n showFixtures ||\n (fixtures.length > 0 &&\n listed.length === 0 &&\n folded.length === 0 &&\n query.trim().length === 0);\n const searchable = Boolean(more) || organizations.length > SEARCH_APPEARS_ABOVE;\n /**\n * Which display names appear more than once in THIS list — the only rows where the\n * second line earns its space. Computed from the list itself, so the answer is right\n * for the person looking at it rather than for organizations they cannot see.\n */\n const sharesItsName = (org: OrganizationPickerOrganization) =>\n organizations.filter((other) => other.name.trim() === org.name.trim()).length > 1;\n\n const renderRow = (org: OrganizationPickerOrganization) => {\n const isActive = org.id === activeOrganizationId;\n const favorite = isFavorite(org.id);\n return (\n <li key={org.id} role=\"none\" className=\"group/org relative flex items-center\">\n {look === \"menu\" ? (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n aria-pressed={isActive}\n onClick={(event) => {\n event.stopPropagation();\n onSelect(org);\n }}\n className={MENU_LOOK_CLASS.item}\n data-active={isActive ? \"\" : undefined}\n data-current={isActive ? \"\" : undefined}\n data-end-button={onToggleFavorite || favorite ? \"\" : undefined}\n >\n <MenuLookRowBody\n icon={<OrganizationMark id={org.id} name={org.name} abbreviation={org.abbreviation} size={16} />}\n label={org.name}\n description={sharesItsName(org) && org.distinguisher ? org.distinguisher : undefined}\n trail={org.detail ?? undefined}\n current={isActive}\n />\n </button>\n ) : (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n aria-pressed={isActive}\n onClick={(event) => {\n // Inside a host menu the click must not also close/route the menu.\n event.stopPropagation();\n onSelect(org);\n }}\n className={cn(\n \"flex w-full min-w-0 items-center gap-2.5 rounded-md py-1.5 pl-2 pr-8 text-left text-sm text-foreground transition-colors hover:bg-accent\",\n isActive && \"bg-primary/10 font-semibold text-primary-ink ring-1 ring-inset ring-primary/30 hover:bg-primary/15\",\n )}\n data-active={isActive ? \"\" : undefined}\n >\n <OrganizationMark id={org.id} name={org.name} abbreviation={org.abbreviation} size={20} />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate\">{org.name}</span>\n {/* Only where the name does not settle it — see `distinguisher`. */}\n {sharesItsName(org) && org.distinguisher ? (\n <span className=\"truncate text-[10px] font-normal text-muted-foreground\">\n {org.distinguisher}\n </span>\n ) : null}\n </span>\n {org.detail ? (\n <span\n className=\"shrink-0 text-xs font-normal text-muted-foreground\"\n data-slot=\"organization-picker-detail\"\n >\n {org.detail}\n </span>\n ) : null}\n {isActive && (\n <CheckIcon className=\"h-[15px] w-[15px] shrink-0 text-primary-ink\" />\n )}\n </button>\n )}\n {/* THE STAR — its own button beside the row, never part of it: a star\n favorites, it never selects. Shown on hover/focus, always shown\n while favorited. Read-only (a mark) when the host has no write. */}\n {onToggleFavorite ? (\n <button\n type=\"button\"\n aria-pressed={favorite}\n aria-label={favorite ? `Remove ${org.name} from favorites` : `Add ${org.name} to favorites`}\n title={favorite ? \"Remove from favorites\" : \"Add to favorites\"}\n onClick={(event) => {\n event.stopPropagation();\n onToggleFavorite(org.id, !favorite);\n }}\n className={cn(\n \"absolute right-1 flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100\",\n favorite ? \"opacity-100\" : \"opacity-0 group-hover/org:opacity-100\",\n )}\n data-slot=\"organization-picker-favorite\"\n >\n <StarIcon\n className={cn(\"h-[14px] w-[14px]\", favorite && \"fill-warning text-warning-ink\")}\n />\n </button>\n ) : favorite ? (\n <StarIcon\n className=\"absolute right-2 h-[13px] w-[13px] fill-warning text-warning-ink\"\n aria-hidden={false}\n aria-label=\"Favorite\"\n role=\"img\"\n />\n ) : null}\n </li>\n );\n };\n\n return (\n <div className={cn(\"flex flex-col\", className)} data-slot=\"organization-picker\">\n {!hideHeading && (\n <p className=\"px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Organization\n </p>\n )}\n\n {loading ? (\n <div className=\"space-y-1 px-1 py-1\" aria-busy=\"true\" aria-label=\"Loading organizations\">\n <Skeleton className=\"h-7 rounded-md\" />\n <Skeleton className=\"h-7 rounded-md\" />\n </div>\n ) : loadFailed ? (\n <ErrorBox\n className=\"px-2 py-2 text-xs text-destructive-ink\"\n operation=\"Load your organizations\"\n origin=\"design-system/OrganizationPicker\"\n >\n Could not load organizations.\n </ErrorBox>\n ) : organizations.length === 0 && !(more && query.trim()) ? (\n <p className=\"px-2 py-2 text-xs text-muted-foreground\">\n Your account is not a member of any organization. Ask an administrator to add you to one.\n </p>\n ) : (\n <>\n {/* SEARCH. A list a person scrolls nine rows at a time is not a\n control, it is a filing cabinet (VERIFIER-8 MEDIUM-3). Name and\n abbreviation, case-insensitive substring; an empty box is exactly\n the list that was there before. */}\n {searchable && (\n <div className=\"px-2 pb-1.5\">\n <Input\n type=\"search\"\n value={query}\n onChange={(event) => {\n setQuery(event.target.value);\n more?.onQueryChange(event.target.value);\n }}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => event.stopPropagation()}\n placeholder=\"Search organizations\"\n aria-label=\"Search organizations by name or abbreviation\"\n className=\"h-8 text-sm\"\n data-slot=\"organization-picker-search\"\n />\n </div>\n )}\n\n {listed.length === 0 && folded.length === 0 && fixtures.length === 0 ? (\n <p\n className=\"px-2 py-2 text-xs text-muted-foreground\"\n data-slot=\"organization-picker-no-match\"\n >\n No organization matches “{query.trim()}”.\n </p>\n ) : listed.length === 0 && folded.length > 0 ? null : listed.length === 0 ? (\n /* THE ARCHIVED-ITEMS LAW, honesty half: \"nothing\" may only be said\n when both halves are empty. Here the other half is one line down.\n AND IT SAYS WHAT IS TRUE, NOT WHAT IS EMPTY. The earlier sentence\n read \"Nothing matches “X” outside the test organizations below\" —\n which opens by negating the very rows sitting one click away, and\n `fixtures` IS query-filtered, so those rows ARE matches for X. A\n person reading \"nothing matches\" retypes their search instead of\n clicking. So: count the matches, say where they are, and carry\n the click that reveals them — the same shape as the honest\n empty-filter twin one line down. (TAILS-3) */\n <p\n className=\"px-2 py-2 text-xs text-muted-foreground\"\n data-slot=\"organization-picker-only-fixtures\"\n >\n {query.trim() ? (\n <>\n {fixtures.length === 1\n ? `1 match for “${query.trim()}” is in your test organizations`\n : `All ${fixtures.length} matches for “${query.trim()}” are in your test organizations`}\n {showFixtures ? (\n \", listed below.\"\n ) : (\n <>\n {\" — \"}\n <button\n type=\"button\"\n className=\"underline underline-offset-2 hover:text-foreground\"\n data-slot=\"organization-picker-show-fixtures\"\n onClick={(event) => {\n event.stopPropagation();\n setShowFixtures(true);\n }}\n >\n show them\n </button>\n .\n </>\n )}\n </>\n ) : (\n `Every organization you belong to is a test organization — all ${fixtures.length} are below.`\n )}\n </p>\n ) : (\n <ul className=\"max-h-72 overflow-y-auto\" role=\"listbox\" aria-label=\"Organizations\">\n {listed.map(renderRow)}\n {more?.hasMore && (\n <li role=\"none\">\n <Button\n type=\"button\"\n variant=\"quiet\"\n className=\"w-full justify-start\"\n disabled={more.loadingMore}\n onClick={(event) => {\n event.stopPropagation();\n more.onLoadMore();\n }}\n data-slot=\"organization-picker-more\"\n >\n {more.loadingMore\n ? \"Loading more…\"\n : more.total !== undefined\n ? `Show more (${organizations.length} of ${more.total})`\n : \"Show more\"}\n </Button>\n </li>\n )}\n </ul>\n )}\n\n {/* THE HOST'S FOLD — rows it marked `folded`, counted, one click away. */}\n <ArchivedDisclosure\n count={folded.length}\n open={foldOpen}\n onOpenChange={setShowFolded}\n label={foldedLabel}\n className=\"mt-0.5\"\n >\n <ul className=\"max-h-72 overflow-y-auto\" role=\"listbox\" aria-label={foldedLabel}>\n {folded.map(renderRow)}\n </ul>\n </ArchivedDisclosure>\n\n {/* THE TEST ORGANIZATIONS, behind the platform's ONE archive-style\n disclosure (`ArchivedDisclosure`, the archived-items law). Hidden\n by default, counted out loud, one click away — never silently\n dropped. */}\n <ArchivedDisclosure\n count={fixtures.length}\n open={fixturesOpen}\n onOpenChange={setShowFixtures}\n label=\"Test organizations\"\n className=\"mt-0.5\"\n >\n <ul\n className=\"max-h-72 overflow-y-auto\"\n role=\"listbox\"\n aria-label=\"Test organizations\"\n >\n {fixtures.map(renderRow)}\n </ul>\n </ArchivedDisclosure>\n\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\n\n/**\n * A 6 px status mark. Fills are SIGNAL colors — bright, saturated, the same family the leading\n * agent tools use (blue working, amber waiting, green done, red failed) — never the text-contrast\n * `--warning`/`--success` tokens, which a host darkens for readable text and which read as brown\n * and olive at dot size. A host re-tints any tone with `--dot-<tone>` (HSL triplet).\n * `ring` is the hollow variant for icon corners, where a filled dot reads as \"unread\".\n */\nexport type StatusTone = \"info\" | \"warning\" | \"danger\" | \"success\" | \"neutral\";\n\nconst FILL: Record<StatusTone, string> = {\n info: \"bg-[hsl(var(--dot-info,217_91%_60%))]\",\n warning: \"bg-[hsl(var(--dot-warning,38_92%_50%))]\",\n danger: \"bg-[hsl(var(--dot-danger,0_84%_60%))]\",\n success: \"bg-[hsl(var(--dot-success,142_71%_45%))]\",\n neutral: \"bg-muted-foreground/50\",\n};\n\nconst RING: Record<StatusTone, string> = {\n info: \"border-[hsl(var(--dot-info,217_91%_60%))]\",\n warning: \"border-[hsl(var(--dot-warning,38_92%_50%))]\",\n danger: \"border-[hsl(var(--dot-danger,0_84%_60%))]\",\n success: \"border-[hsl(var(--dot-success,142_71%_45%))]\",\n neutral: \"border-muted-foreground/50\",\n};\n\nexport interface StatusDotProps extends React.HTMLAttributes<HTMLSpanElement> {\n tone: StatusTone;\n variant?: \"solid\" | \"ring\";\n /** Accessible name; without it the dot is decorative. */\n label?: string;\n}\n\nexport function StatusDot({ tone, variant = \"solid\", label, className, ...props }: StatusDotProps) {\n return (\n <span\n data-slot=\"status-dot\"\n data-tone={tone}\n data-variant={variant}\n {...(label ? { role: \"img\", \"aria-label\": label } : { \"aria-hidden\": true })}\n className={cn(\n \"inline-block shrink-0 rounded-full\",\n variant === \"solid\" ? cn(\"size-1.5\", FILL[tone]) : cn(\"size-2 border-[1.5px] bg-transparent\", RING[tone]),\n className,\n )}\n {...props}\n />\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../tooltip\";\nimport { StatusDot, type StatusTone } from \"./status-dot\";\n\n/**\n * The app rail: a narrow, never-changing strip of area icons on the far left, with the\n * person at the bottom (Codex, VS Code, Slack, Teams). It answers \"where am I\"; the panel\n * beside it answers \"what can I do here\". Width is the `--app-rail-width` knob (48 px).\n */\n\nexport function AppRail({ className, style, onKeyDown, ...props }: React.HTMLAttributes<HTMLElement>) {\n return (\n <nav\n data-slot=\"app-rail\"\n aria-label=\"Areas\"\n // Up/Down move between the rail's items, Home/End jump to the ends (a source list's keys).\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || ![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key)) return;\n const items = Array.from(event.currentTarget.querySelectorAll<HTMLElement>(\"[data-slot=app-rail-item]:not(:disabled), [data-slot=app-rail-avatar]\"));\n const at = items.indexOf(event.target as HTMLElement);\n if (at === -1) return;\n const next = event.key === \"Home\" ? 0 : event.key === \"End\" ? items.length - 1 : at + (event.key === \"ArrowDown\" ? 1 : -1);\n const target = items[Math.max(0, Math.min(items.length - 1, next))];\n if (target) {\n event.preventDefault();\n target.focus();\n }\n }}\n className={cn(\"flex h-full w-(--app-rail-width) shrink-0 flex-col items-center gap-1 py-2\", className)}\n style={{ \"--app-rail-width\": \"48px\", ...style } as React.CSSProperties}\n {...props}\n />\n );\n}\n\nexport function AppRailGroup({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div data-slot=\"app-rail-group\" className={cn(\"flex flex-col items-center gap-1\", className)} {...props} />;\n}\n\n/** Pushes everything after it to the bottom of the rail. */\nexport function AppRailSpacer() {\n return <div data-slot=\"app-rail-spacer\" className=\"flex-1\" />;\n}\n\nexport interface AppRailItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n icon: React.ReactNode;\n label: string;\n /** Shown in the tooltip after the label, e.g. \"⌘1\". */\n shortcut?: string;\n active?: boolean;\n /** A hollow corner mark when the area needs attention; healthy areas carry none. */\n attention?: StatusTone;\n attentionLabel?: string;\n}\n\nexport const AppRailItem = React.forwardRef<HTMLButtonElement, AppRailItemProps>(function AppRailItem(\n { icon, label, shortcut, active = false, attention, attentionLabel, className, ...props },\n ref,\n) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n data-slot=\"app-rail-item\"\n data-active={active}\n aria-label={label}\n aria-current={active ? \"page\" : undefined}\n className={cn(\n \"relative flex size-8 items-center justify-center rounded-lg text-muted-foreground outline-none transition-colors\",\n \"hover:bg-foreground/[0.06] hover:text-foreground\",\n \"data-[active=true]:bg-foreground/[0.08] data-[active=true]:text-foreground\",\n \"focus-visible:ring-2 focus-visible:ring-ring\",\n \"[&_svg]:size-[18px] [&_svg]:shrink-0\",\n className,\n )}\n {...props}\n >\n {icon}\n {attention ? (\n <StatusDot\n tone={attention}\n variant=\"ring\"\n {...(attentionLabel ? { label: attentionLabel } : {})}\n className=\"absolute right-0.5 bottom-0.5\"\n />\n ) : null}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\">\n <span className=\"flex items-center gap-2\">\n {label}\n {shortcut ? <span className=\"opacity-60\">{shortcut}</span> : null}\n </span>\n </TooltipContent>\n </Tooltip>\n );\n});\n\nexport interface AppRailAvatarProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n /** Up to two letters. Ignored when `children` is given. */\n initials?: string;\n label: string;\n /** A glyph instead of initials (e.g. a neutral person while signed out). */\n children?: React.ReactNode;\n}\n\n/** The person, at the bottom of the rail (Codex's initials circle). */\nexport const AppRailAvatar = React.forwardRef<HTMLButtonElement, AppRailAvatarProps>(function AppRailAvatar(\n { initials = \"\", label, className, children, ...props },\n ref,\n) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n data-slot=\"app-rail-avatar\"\n aria-label={label}\n className={cn(\n \"flex size-6 items-center justify-center rounded-full bg-foreground/[0.12] text-[10px] font-semibold leading-none text-muted-foreground outline-none [&_svg]:size-3.5\",\n \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n className,\n )}\n {...props}\n >\n {children ?? initials.slice(0, 2).toUpperCase()}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\">\n {label}\n </TooltipContent>\n </Tooltip>\n );\n});\n","\"use client\";\n\n/**\n * Resizable — the split-pane family, on react-resizable-panels **v4**.\n *\n * TWO FORKS COLLAPSE INTO ONE COMPONENT. matrx-frontend shipped\n * `components/ui/resizable.tsx` (38 import sites, one fixed handle width) AND\n * `components/ui/matrx/resizable.tsx` (6 sites, an eight-step `size` scale).\n * They disagreed about exactly one thing — how thick the handle is — which is\n * the C18 density-as-a-fork pattern this package exists to end. `size` is a\n * prop here; both forks die.\n *\n * v4 IS NOT v1/v2, and the differences are the reason a wrapper exists at all:\n * - the group prop is `orientation`, not `direction`;\n * - `data-panel-group-direction` is gone — the separator states\n * `aria-orientation`, and it is `vertical` in a HORIZONTAL group (it is the\n * separator's own axis, not the group's), which is why every orientation\n * selector below reads the way it does;\n * - `Group` sets `height:100%/width:100%/overflow:hidden` internally;\n * - `Panel` renders an outer flex-sizing div wrapping an inner\n * `overflow:auto` div that receives `className`/`style` — to make a panel\n * clip instead of scroll, pass `style={{ overflow: \"hidden\", height: \"100%\" }}`;\n * - numeric size props are PIXELS; percentages are strings (`\"30%\"`).\n *\n * THE DRAG OUTLINE BUG, kept fixed. The library sets `tabIndex=0` on the\n * separator, so a mouse drag FOCUSES it and the browser's default outline\n * flashes — which rendered as a near-white bar in dark mode. `focus-visible:`\n * does not suppress it (that is keyboard-only); `focus:outline-none` does, and\n * the keyboard ring is restored explicitly on `focus-visible`.\n *\n * MOUSE TOLERANCE IS AN INVISIBLE TARGET. A 2px line is not grabbable; an\n * `::after` overlay widens the hit area without widening the rule, and goes to\n * 44px on coarse pointers.\n *\n * `react-resizable-panels` is an ordinary dependency, not a peer (C23): the\n * panel geometry IS this component's product.\n */\n\nimport * as React from \"react\";\nimport { Group, Panel, Separator } from \"react-resizable-panels\";\n\nimport { cn } from \"./cn\";\nimport { DragHandleDots2Icon } from \"./icons\";\n\nexport type ResizableHandleSize =\n | \"xs\"\n | \"sm\"\n | \"md\"\n | \"lg\"\n | \"xl\"\n | \"2xl\"\n | \"3xl\"\n | \"4xl\";\n\n/**\n * The separator's own thickness. `aria-orientation=horizontal` means a\n * separator lying across a VERTICAL group, so its thickness is a height.\n */\nconst HANDLE_SIZES: Record<ResizableHandleSize, string> = {\n xs: \"w-0.5 [&[aria-orientation=horizontal]]:h-0.5 [&[aria-orientation=horizontal]]:w-full\",\n sm: \"w-1 [&[aria-orientation=horizontal]]:h-1 [&[aria-orientation=horizontal]]:w-full\",\n md: \"w-1.5 [&[aria-orientation=horizontal]]:h-1.5 [&[aria-orientation=horizontal]]:w-full\",\n lg: \"w-2 [&[aria-orientation=horizontal]]:h-2 [&[aria-orientation=horizontal]]:w-full\",\n xl: \"w-3 [&[aria-orientation=horizontal]]:h-3 [&[aria-orientation=horizontal]]:w-full\",\n \"2xl\":\n \"w-4 [&[aria-orientation=horizontal]]:h-4 [&[aria-orientation=horizontal]]:w-full\",\n \"3xl\":\n \"w-6 [&[aria-orientation=horizontal]]:h-6 [&[aria-orientation=horizontal]]:w-full\",\n \"4xl\":\n \"w-8 [&[aria-orientation=horizontal]]:h-8 [&[aria-orientation=horizontal]]:w-full\",\n};\n\nconst ResizablePanelGroup = ({\n className,\n ...props\n}: React.ComponentProps<typeof Group>) => (\n <Group\n data-slot=\"resizable-group\"\n className={cn(\"flex h-full w-full\", className)}\n {...props}\n />\n);\nResizablePanelGroup.displayName = \"ResizablePanelGroup\";\n\nconst ResizablePanel = Panel;\n\nexport interface ResizableHandleProps\n extends React.ComponentProps<typeof Separator> {\n /** Render the centered grip. */\n withHandle?: boolean;\n /** Separator thickness. Default `xs` — matrx-frontend's original 2px line. */\n size?: ResizableHandleSize;\n}\n\nconst ResizableHandle = ({\n withHandle,\n size = \"xs\",\n className,\n ...props\n}: ResizableHandleProps) => (\n <Separator\n data-slot=\"resizable-handle\"\n className={cn(\n \"group/handle relative flex shrink-0 items-center justify-center bg-border transition-colors\",\n // Invisible hit target centered on the line; wider still on touch.\n \"after:absolute after:inset-y-0 after:left-1/2 after:w-1.5 after:-translate-x-1/2 after:content-['']\",\n \"pointer-coarse:after:w-11\",\n \"[&[aria-orientation=horizontal]]:after:inset-x-0 [&[aria-orientation=horizontal]]:after:left-0 [&[aria-orientation=horizontal]]:after:top-1/2 [&[aria-orientation=horizontal]]:after:h-1.5 [&[aria-orientation=horizontal]]:after:w-full [&[aria-orientation=horizontal]]:after:-translate-x-0 [&[aria-orientation=horizontal]]:after:-translate-y-1/2\",\n \"pointer-coarse:[&[aria-orientation=horizontal]]:after:h-11\",\n // The drag-outline bug: suppress for ALL focus, restore for keyboard.\n \"focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1\",\n // Library-driven state feedback.\n \"data-[separator=hover]:bg-primary data-[separator=active]:bg-primary\",\n HANDLE_SIZES[size],\n \"cursor-col-resize [&[aria-orientation=horizontal]]:cursor-row-resize\",\n className,\n )}\n {...props}\n >\n {withHandle ? (\n <div className=\"z-10 flex h-8 w-4 items-center justify-center rounded-sm border bg-border group-aria-[orientation=horizontal]/handle:h-4 group-aria-[orientation=horizontal]/handle:w-8\">\n <DragHandleDots2Icon className=\"h-2.5 w-2.5 group-aria-[orientation=horizontal]/handle:rotate-90\" />\n </div>\n ) : null}\n </Separator>\n);\nResizableHandle.displayName = \"ResizableHandle\";\n\nexport { ResizableHandle, ResizablePanel, ResizablePanelGroup };\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { ResizableHandle, ResizablePanel, ResizablePanelGroup } from \"../resizable\";\n\n/**\n * The canvas: a right-hand workspace of panels (terminal, files, browser, info) beside the\n * main content, as in Claude desktop and Codex. Panels stack in columns, resize by dragging\n * the gaps between them, and any one can expand to fill the whole canvas region.\n *\n * The layout is presentational: the host owns which panels are open, which is expanded and\n * what each renders. The panel CHROME (CanvasPanel, CanvasPanelEmpty, BrowserTabs, BrowserBar)\n * lives in @ai-matrx/canvas/react — the one canvas chrome; this package cannot depend on it\n * (canvas → tap-target → design-system would be a cycle).\n */\n\nexport interface CanvasPanelDef {\n id: string;\n node: React.ReactNode;\n /** Pixels (number) or percent of the column (string). */\n minSize?: number | string;\n defaultSize?: number | string;\n}\n\nexport interface CanvasColumnDef {\n id: string;\n panels: CanvasPanelDef[];\n minSize?: number | string;\n defaultSize?: number | string;\n}\n\nexport interface CanvasLayoutProps {\n columns: CanvasColumnDef[];\n /** When set, only this panel renders, filling the layout. */\n expandedId?: string | null;\n className?: string;\n}\n\nconst GAP = \"bg-transparent data-[separator=hover]:bg-foreground/15 data-[separator=active]:bg-foreground/25\";\n\nexport function CanvasLayout({ columns, expandedId = null, className }: CanvasLayoutProps) {\n const visible = columns.filter((c) => c.panels.length > 0);\n const expanded = expandedId ? visible.flatMap((c) => c.panels).find((p) => p.id === expandedId) : undefined;\n\n if (expanded) {\n return (\n <div data-slot=\"canvas-layout\" data-expanded={expanded.id} className={cn(\"flex h-full w-full\", className)}>\n {expanded.node}\n </div>\n );\n }\n\n return (\n <ResizablePanelGroup data-slot=\"canvas-layout\" orientation=\"horizontal\" className={cn(\"gap-0\", className)}>\n {visible.map((column, ci) => (\n <React.Fragment key={column.id}>\n {ci > 0 ? <ResizableHandle data-canvas-gap=\"column\" size=\"md\" className={GAP} /> : null}\n <ResizablePanel\n id={column.id}\n minSize={column.minSize ?? 220}\n {...(column.defaultSize !== undefined ? { defaultSize: column.defaultSize } : {})}\n >\n <ResizablePanelGroup data-canvas-column={column.id} orientation=\"vertical\">\n {column.panels.map((panel, pi) => (\n <React.Fragment key={panel.id}>\n {pi > 0 ? <ResizableHandle data-canvas-gap=\"row\" size=\"md\" className={GAP} /> : null}\n <ResizablePanel\n id={panel.id}\n minSize={panel.minSize ?? 120}\n {...(panel.defaultSize !== undefined ? { defaultSize: panel.defaultSize } : {})}\n >\n {panel.node}\n </ResizablePanel>\n </React.Fragment>\n ))}\n </ResizablePanelGroup>\n </ResizablePanel>\n </React.Fragment>\n ))}\n </ResizablePanelGroup>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../tooltip\";\n\n/**\n * A small segmented group of icon buttons for switching the app's mode (Claude desktop's\n * chat | code pair in the title bar). A radio group: arrow keys move, one is always checked.\n */\n\nexport interface ModeSwitchOption<T extends string> {\n value: T;\n label: string;\n icon: React.ReactNode;\n shortcut?: string;\n}\n\nexport interface ModeSwitchProps<T extends string> {\n value: T;\n onValueChange: (value: T) => void;\n options: ReadonlyArray<ModeSwitchOption<T>>;\n label?: string;\n className?: string;\n}\n\nexport function ModeSwitch<T extends string>({ value, onValueChange, options, label = \"Mode\", className }: ModeSwitchProps<T>) {\n const refs = React.useRef<Array<HTMLButtonElement | null>>([]);\n\n const move = (from: number, delta: number) => {\n const next = (from + delta + options.length) % options.length;\n const option = options[next];\n if (!option) return;\n onValueChange(option.value);\n refs.current[next]?.focus();\n };\n\n return (\n <div\n role=\"radiogroup\"\n aria-label={label}\n data-slot=\"mode-switch\"\n className={cn(\"inline-flex items-center gap-0.5 rounded-lg bg-foreground/[0.06] p-0.5\", className)}\n >\n {options.map((option, index) => {\n const checked = option.value === value;\n return (\n <Tooltip key={option.value}>\n <TooltipTrigger asChild>\n <button\n ref={(el) => {\n refs.current[index] = el;\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={checked}\n aria-label={option.label}\n data-slot=\"mode-switch-item\"\n data-value={option.value}\n tabIndex={checked ? 0 : -1}\n onClick={() => onValueChange(option.value)}\n onKeyDown={(event) => {\n if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n move(index, 1);\n } else if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n move(index, -1);\n }\n }}\n className={cn(\n \"flex h-6 w-7 items-center justify-center rounded-md text-muted-foreground outline-none transition-colors\",\n \"hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\",\n \"aria-checked:bg-background aria-checked:text-foreground aria-checked:shadow-[0_0_0_0.5px_hsl(var(--foreground)/0.12),0_1px_2px_hsl(var(--foreground)/0.08)]\",\n \"dark:aria-checked:bg-foreground/[0.14] dark:aria-checked:shadow-none\",\n \"[&_svg]:size-[15px] [&_svg]:shrink-0\",\n )}\n >\n {option.icon}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n <span className=\"flex items-center gap-2\">\n {option.label}\n {option.shortcut ? <span className=\"opacity-60\">{option.shortcut}</span> : null}\n </span>\n </TooltipContent>\n </Tooltip>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["React","jsx","React","jsx","jsxs","isActive","jsx","React","jsx","jsxs","AppRailItem","AppRailAvatar","jsx","React","jsx","jsxs","React","jsx","jsxs"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/item/types.ts","../src/item/host.tsx","../src/item/run-entry.ts","../src/item/ItemMenu.tsx","../src/item/ItemMenuDrawer.tsx","../src/item/ItemRow.tsx"],"sourcesContent":["/**\n * Item system — shared schema + prop types for ItemRow and ItemMenu.\n * Moved whole from @ai-matrx/chat/ui/item-types (2026-10-08); chat re-exports\n * these and narrows the surface fields to its closed registries.\n *\n * Pure types (no JSX). The menu config is a structured `sections` array with a\n * discriminated union of entries (`kind`), so ordering is explicit, section\n * labels are first-class, separators fall out of section boundaries, and\n * submenus nest naturally.\n *\n * Consumed by ItemMenu.tsx, ItemMenuDrawer.tsx, ItemRow.tsx.\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\n/** Any icon component taking a className (lucide-react icons fit as-is). */\nexport type ItemMenuIcon = ComponentType<{ className?: string | undefined }>;\n\n/**\n * The record a row stands for, as the host's right-click menu reads it.\n * Structural on purpose: design-system knows no entity registry. A host\n * (chat) narrows it to its own `ContextMenuEntityRef`.\n */\nexport interface ItemEntityRef {\n type?: string | undefined;\n id?: string | undefined;\n title?: string | undefined;\n}\n\n// ── Menu entries ────────────────────────────────────────────────────────────\n\ninterface ItemMenuEntryBase {\n /** Stable identity within the menu. React key + shortcut/debug target. */\n id: string;\n label: string;\n icon?: ItemMenuIcon | undefined;\n /**\n * Semantic color class for the icon ONLY (e.g. \"text-amber-500\" for a pin).\n * Destructive entries use `tone: \"destructive\"`, never an iconClassName.\n */\n iconClassName?: string | undefined;\n /**\n * Hover text for the entry — never a second line (Arman, 2026-10-14: no\n * \"novels\" in menus). A menu is a list of verbs; the only second line an\n * entry draws is its `disabledReason`.\n */\n description?: string | undefined;\n /**\n * Short trailing chip, right-aligned on the same line (\"Coming soon\", \"Beta\",\n * \"Pro\"). This is the RIGHT way to qualify an entry — it costs no height,\n * unlike `description`. One or two words; it is a tag, not a sentence.\n */\n badge?: string | undefined;\n /** Omit the entry entirely. Builders compute this at config-build time. */\n hidden?: boolean | undefined;\n disabled?: boolean | undefined;\n /** Why it's disabled — rendered inline (muted) and as a `title` tooltip. */\n disabledReason?: string | undefined;\n}\n\n/** Visual + semantic severity. Destructive renders text/icon in text-destructive. */\nexport type ItemMenuTone = \"default\" | \"destructive\";\n\nexport interface ItemMenuToast {\n loading: string;\n success: string;\n /** Static message, or derive one from the thrown error. */\n error?: (string | ((error: unknown) => string)) | undefined;\n}\n\n/** A plain action. The default entry kind. */\nexport interface ItemMenuCommand extends ItemMenuEntryBase {\n kind?: \"command\" | undefined;\n tone?: ItemMenuTone | undefined;\n /**\n * Runs synchronously in the select handler (preserves the user-gesture\n * context required by clipboard writes), then the menu closes. If it\n * returns a Promise AND `toast` is set, the promise is handed to\n * sonner's `toast.promise`. If it returns a Promise WITHOUT `toast`, it's\n * fire-and-forget (the action owns its own optimistic update + feedback —\n * the conversation-thunk pattern). Void → nothing.\n */\n onSelect: () => void | Promise<void>;\n toast?: ItemMenuToast | undefined;\n /** Display-only shortcut hint, right-aligned (\"⌘D\", \"R\"). Desktop only. */\n shortcut?: string | undefined;\n /**\n * Single character that activates this entry while the menu is open\n * (Claude Code style: P/R/A/D). Case-insensitive, no modifiers.\n */\n shortcutKey?: string | undefined;\n /**\n * Declarative hook for host components. ItemRow intercepts `\"rename\"` and\n * starts its inline rename INSTEAD of running `onSelect`. Standalone\n * ItemMenu ignores intent and runs `onSelect` (keep a dialog fallback\n * there for non-row surfaces).\n */\n intent?: \"rename\" | undefined;\n}\n\n/**\n * A persistent on/off toggle (Radix CheckboxItem desktop, check glyph in the\n * drawer). Selecting it does NOT close the menu — it's a view option.\n *\n * RESERVED for genuine view options (\"Show timestamps\", \"Compact rows\").\n * State-FLIP actions (Pin/Unpin, Archive/Unarchive) stay plain `command`s\n * whose label+icon the builder swaps from current state.\n */\nexport interface ItemMenuCheckbox extends ItemMenuEntryBase {\n kind: \"checkbox\";\n checked: boolean;\n /** Should be optimistic. Failures are the caller's to toast + revert. */\n onCheckedChange: (next: boolean) => void | Promise<void>;\n shortcut?: string | undefined;\n shortcutKey?: string | undefined;\n}\n\n/** A real <a>. Gives middle-click / cmd-click semantics inside the menu. */\nexport interface ItemMenuLink extends ItemMenuEntryBase {\n kind: \"link\";\n href: string;\n /** \"_blank\" adds rel=\"noopener noreferrer\" automatically. */\n target?: \"_blank\" | undefined;\n}\n\n/** Nested submenu — Radix Sub on desktop, drill-in view on the drawer. */\nexport interface ItemMenuSubmenu extends ItemMenuEntryBase {\n kind: \"submenu\";\n /** Submenu body. Sections render with separators between them. */\n sections: ItemMenuSection[];\n /** Embed an existing canonical menu without duplicating its commands. */\n renderContent?: ((onClose: () => void) => ReactNode) | undefined;\n}\n\nexport type ItemMenuEntry =\n ItemMenuCommand | ItemMenuCheckbox | ItemMenuLink | ItemMenuSubmenu;\n\n// ── Sections + config ───────────────────────────────────────────────────────\n\nexport interface ItemMenuSection {\n /** React key. Defaults to `label` ?? index. Provide when label is absent. */\n id?: string | undefined;\n /** Optional muted heading (\"Manage\", \"Danger\"). */\n label?: string | undefined;\n items: ItemMenuEntry[];\n}\n\nexport interface ItemMenuHeader {\n /** e.g. the row title. The drawer renders it as DrawerTitle. */\n title: string;\n description?: string | undefined;\n}\n\nexport interface ItemMenuConfig {\n /** Optional header. Desktop renders a muted label row; drawer a real header. */\n header?: ItemMenuHeader | undefined;\n /** Separators are derived from section boundaries — never declared. */\n sections: ItemMenuSection[];\n}\n\n/**\n * Lazy form: invoked when the menu opens, so big lists don't build N configs\n * per render. Either form is accepted anywhere a config is.\n */\nexport type ItemMenuConfigInput = ItemMenuConfig | (() => ItemMenuConfig);\n\n// ── ItemMenu component props ────────────────────────────────────────────────\n\nexport interface ItemMenuProps {\n config: ItemMenuConfigInput;\n /** The trigger element — rendered via Radix `asChild` (must accept a ref). */\n children: ReactNode;\n /** Dropdown alignment relative to trigger. Default \"end\". */\n align?: \"start\" | \"center\" | \"end\" | undefined;\n side?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n /**\n * Controlled open state. Pass when a surface opens the menu from outside the\n * trigger (e.g. whole-row click opens the same kebab menu). Omit for the\n * default uncontrolled trigger-driven behavior.\n */\n open?: boolean | undefined;\n /** Observe / drive open state (e.g. ItemRow pins the kebab visible while open). */\n onOpenChange?: ((open: boolean) => void) | undefined;\n /**\n * Radix `onCloseAutoFocus` passthrough. ItemRow uses it to move focus into\n * the rename input instead of back to the kebab. Desktop only.\n */\n onCloseAutoFocus?: ((event: Event) => void) | undefined;\n /** Force presentation. Default: useIsMobile(). For demos/tests. */\n presentation?: \"auto\" | \"dropdown\" | \"drawer\" | undefined;\n}\n\n/**\n * What the row IS, forwarded to the v3 context menu.\n *\n * This is the slot that was dark. `entity` gates **Attach To** and **Share**\n * inside `MenuContent`; `ItemContextMenu` never passed one, so every consumer\n * of the item system was denied both — not because the capability was missing,\n * but because the wrapper dropped it on the floor. `sourceFeature` was worse\n * than absent: it was hardcoded `\"files\"` for every caller, so a note row's\n * agent launches were attributed to the files feature.\n */\nexport interface ItemMenuSurface {\n /**\n * REQUIRED. v3 attributes every shortcut and agent launched from this menu\n * to it, and the type is a closed registry — there is deliberately no\n * generic member to hide behind.\n */\n sourceFeature: string;\n /** Registry surface name, when the row's surface has one (AI actions, bound agents). */\n surfaceName?: string | undefined;\n /**\n * The record itself. Present → Attach To. With `resourceType` → Share too.\n * Omit only when the row does not correspond to a registered entity.\n */\n entity?: ItemEntityRef | undefined;\n}\n\nexport interface ItemContextMenuProps extends ItemMenuSurface {\n config: ItemMenuConfigInput;\n /** The right-clickable surface (usually the whole row). */\n children: ReactNode;\n onOpenChange?: ((open: boolean) => void) | undefined;\n onCloseAutoFocus?: ((event: Event) => void) | undefined;\n /**\n * When false, children render bare (no Radix root). ItemRow passes `false`\n * on touch so long-press doesn't fight scroll + the always-visible kebab.\n */\n enabled?: boolean | undefined;\n /**\n * Live surface values for the universal menu. A delegated pane menu uses\n * the same scope builder as its SurfaceRuntimeProvider, so AI actions never\n * lose the values the surface declares.\n */\n getApplicationScope?: (() => unknown) | undefined;\n /**\n * ONE-MENU-PER-PANE delegation. Resolve the clicked row's existing kebab\n * config and per-row context from the event target at open time.\n */\n resolveItemOnOpen?: (target: HTMLElement | null) => {\n config: ItemMenuConfigInput;\n context?: unknown | undefined;\n } | null;\n}\n\n// ── ItemRow props ───────────────────────────────────────────────────────────\n\nexport interface ItemRowRename {\n /** Text being renamed. Defaults to `label`. */\n value?: string | undefined;\n onCommit: (next: string) => void | Promise<void>;\n validate?: ((next: string) => string | null) | undefined;\n emptyFallback?: string | undefined;\n maxLength?: number | undefined;\n /** Allow double-click on the row to start renaming. Default true. */\n doubleClick?: boolean | undefined;\n}\n\nexport interface ItemRowDisclosure {\n /** Whether the sub-list is showing (sets `aria-expanded`). */\n open: boolean;\n onToggle: () => void;\n /** Screen-reader name; absent = \"Expand <label>\" / \"Collapse <label>\". */\n ariaLabel?: string | undefined;\n}\n\nexport type ItemRowSize = \"xs\" | \"sm\" | \"md\" | \"lg\"; // h-6 nested sub-row (muted) / h-7 / h-8 (default) / h-10\n\nexport interface ItemRowProps extends ItemMenuSurface {\n label: string;\n /** Muted, never masked; sits between label and trailing indicators. */\n secondaryLabel?: string | undefined;\n /**\n * The most room the secondary label may take before it truncates (the label keeps the rest).\n * \"half\" (default) or \"third\" — for a secondary that only explains the row (a search reason).\n */\n secondaryShare?: \"half\" | \"third\" | undefined;\n /**\n * A second line under the label (a record's owner, path or snippet). The row\n * grows to two lines; the label keeps its fade, the subtitle is cut with an ellipsis.\n */\n subtitle?: ReactNode;\n /**\n * Controls at the row's trailing edge, OUTSIDE the row's link/button (so a\n * button here is never nested in the row's own control). With `actions`, the\n * kebab sits in the same group instead of floating over the label.\n */\n actions?: ReactNode;\n /** A control before the row's link/button (a selection checkbox), outside it. */\n leadingControl?: ReactNode;\n /**\n * The row folds a sub-list (a conversation's helpers, a folder's children). THE DISCLOSURE IS ON\n * THE RIGHT (Arman, 2026-10-23: \"CHEVRONS DO NOT GO ON THE LEFT SIDE of things\"): a chevron button\n * at the row's trailing edge, outside the row's link, after the trailing indicators; the label\n * keeps the column's one left edge. Never draw a chevron in `leading`.\n */\n disclosure?: ItemRowDisclosure | undefined;\n /**\n * Keep the disclosure's trailing room even with no `disclosure` — pass it on the plain rows that\n * sit among disclosure rows so every row's trailing meta (time) ends on one right edge.\n */\n reserveDisclosure?: boolean | undefined;\n /** Icon / status-dot slot. Fixed-width content recommended (size-4). */\n leading?: ReactNode;\n /**\n * Indicator slot (star, streaming dot). Sits at the right edge at rest and\n * glides LEFT (translate) when the kebab is revealed. Never masked.\n */\n trailing?: ReactNode;\n /**\n * Meta shown only while the row is hovered, keyboard-focused or its menu is open (a chat's\n * relative time). At rest it takes no room, so `trailing` keeps the right edge. Always shown on\n * touch, where the kebab is always shown too.\n */\n trailingOnHover?: ReactNode;\n active?: boolean | undefined;\n disabled?: boolean | undefined;\n /** Navigation mode — renders next/link as the row's primary element. */\n href?: string | undefined;\n /** Click mode — renders a <button> primary. Ignored while renaming. */\n onOpen?: (() => void) | undefined;\n /**\n * Only meaningful alongside `href`. By default a plain click navigates to\n * `href` and `onOpen` runs as a side effect (close a popover, etc.). When\n * `true`, a plain left-click instead calls `onOpen` and PREVENTS navigation —\n * for self-contained surfaces (drawers, embedded panels) that open the target\n * in place rather than routing the page away. The `href` is kept so\n * modifier/middle-click still opens it in a new tab and \"Copy link\" still\n * works. Default false.\n */\n openInPlace?: boolean | undefined;\n /** Kebab + right-click menu. Omit for menu-less rows. */\n menu?: ItemMenuConfigInput | undefined;\n /**\n * `sourceFeature` / `surfaceName` / `entity` (inherited from\n * `ItemMenuSurface`) are forwarded to the right-click menu. **Pass `entity`**\n * — it is what turns Attach To and Share on, and every row that omits it\n * ships a menu missing two doors the platform already has.\n */\n /** Inline rename. Enables double-click + the `intent: \"rename\"` contract. */\n rename?: ItemRowRename | undefined;\n size?: ItemRowSize | undefined; // default \"md\"\n /** Tree depth. padding-inline-start = 8px + indent * 16px. */\n indent?: number | undefined;\n /** Accessible label for the kebab. Default `Options for ${label}`. */\n kebabAriaLabel?: string | undefined;\n /**\n * Suppress ItemRow's own right-click menu (the kebab keeps the config).\n * Set when the host wraps the row in the universal v3 context menu\n * (`features/context-menu-v3`) so right-click belongs to ONE system.\n */\n disableContextMenu?: boolean | undefined;\n className?: string | undefined;\n}\n\n// ── Type guards ─────────────────────────────────────────────────────────────\n\nexport function isCommand(entry: ItemMenuEntry): entry is ItemMenuCommand {\n return entry.kind === undefined || entry.kind === \"command\";\n}\nexport function isCheckbox(entry: ItemMenuEntry): entry is ItemMenuCheckbox {\n return entry.kind === \"checkbox\";\n}\nexport function isLink(entry: ItemMenuEntry): entry is ItemMenuLink {\n return entry.kind === \"link\";\n}\nexport function isSubmenu(entry: ItemMenuEntry): entry is ItemMenuSubmenu {\n return entry.kind === \"submenu\";\n}\n\nexport function resolveItemMenuConfig(\n input: ItemMenuConfigInput,\n): ItemMenuConfig {\n return typeof input === \"function\" ? input() : input;\n}\n","\"use client\";\n\n/**\n * The host seam for the item system (ItemRow / ItemMenu). A host may override\n * it, never NEED to: without a provider the row's right-click opens the same\n * menu config in design-system's own context menu, and a promised command's\n * failure is reported to the console instead of a toast.\n *\n * - `ContextMenu` — the host's universal right-click menu around a row (the\n * website / chat mount the v3 menu here, which adds Copy, agents, Attach To,\n * Share). It receives the full `ItemContextMenuProps`.\n * - `toastPromise` — the host's promise toast (sonner's `toast.promise` shape).\n */\n\nimport * as React from \"react\";\nimport type { ItemContextMenuProps, ItemMenuToast } from \"./types\";\n\nexport interface ItemToastPromise {\n (\n promise: Promise<unknown>,\n messages: { loading: string; success: string; error: (error: unknown) => string },\n ): void;\n}\n\nexport interface ItemMenuHost {\n ContextMenu?: React.ComponentType<ItemContextMenuProps>;\n toastPromise?: ItemToastPromise;\n}\n\nconst HOST_KEY = Symbol.for(\"@ai-matrx/design-system/item-menu-host\");\ntype HostRegistry = Record<symbol, React.Context<ItemMenuHost | null> | undefined>;\nconst hostRegistry = globalThis as unknown as HostRegistry;\nconst ItemMenuHostContext: React.Context<ItemMenuHost | null> =\n hostRegistry[HOST_KEY] ??\n (hostRegistry[HOST_KEY] = React.createContext<ItemMenuHost | null>(null));\n\n/** Mount once at the host's app root. */\nexport function ItemMenuHostProvider({\n host,\n children,\n}: {\n host: ItemMenuHost;\n children: React.ReactNode;\n}) {\n return <ItemMenuHostContext.Provider value={host}>{children}</ItemMenuHostContext.Provider>;\n}\n\nexport function useItemMenuHost(): ItemMenuHost | null {\n return React.useContext(ItemMenuHostContext);\n}\n\nexport type { ItemMenuToast };\n","/**\n * Action dispatch for ItemMenu entries — shared by the kebab/dropdown\n * renderer (ItemMenu.tsx), the drawer, the default right-click menu and any\n * host's right-click converter, so command/toggle semantics (sync-in-gesture\n * execution, promise toast, fire-and-forget promise swallow) can never drift\n * between presentations.\n */\n\nimport type { ItemToastPromise } from \"./host\";\nimport type { ItemMenuCheckbox, ItemMenuCommand } from \"./types\";\n\nexport function runCommand(entry: ItemMenuCommand, toastPromise?: ItemToastPromise) {\n const result = entry.onSelect();\n if (result instanceof Promise) {\n if (entry.toast && toastPromise) {\n const { loading, success, error } = entry.toast;\n toastPromise(result, {\n loading,\n success,\n error: (e) =>\n typeof error === \"function\"\n ? error(e)\n : (error ?? \"Something went wrong\"),\n });\n } else if (entry.toast) {\n // No host toaster: the failure still announces itself.\n result.catch((e) => console.error(`[ItemMenu] \"${entry.label}\" failed`, e));\n } else {\n result.catch(() => {});\n }\n }\n}\n\nexport function runToggle(entry: ItemMenuCheckbox, next: boolean) {\n const result = entry.onCheckedChange(next);\n if (result instanceof Promise) result.catch(() => {});\n}\n","\"use client\";\n\n/**\n * ItemMenu / ItemContextMenu — schema-driven menus rendered three ways from one\n * ItemMenuConfig:\n * - desktop dropdown (kebab trigger) → the one menu look on the Radix\n * dropdown (`MenuLook*`), modal={false}\n * - right-click (wraps a surface) → the host's right-click menu\n * (`ItemMenuHostProvider`; the\n * website/chat mount v3), else the\n * same look on the context menu\n * (`MenuLookContext*`)\n * - mobile (kebab trigger) → Vaul bottom drawer w/ drill-in\n *\n * No dimming backdrop on the dropdown (modal={false}). Command/toggle\n * execution is shared across ALL presentations via run-entry.ts (sync-in-\n * gesture for clipboard, sonner toast.promise), so semantics cannot drift.\n */\n\nimport { Fragment, useEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from \"react\";\nimport { ALCHEMY_GLYPH_PATHS } from \"../content-transfer/icon\";\nimport { declareLazyDataProps, useMatrxTableRowAlchemy, useMatrxTableRowControls } from \"../table-host/host\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport { DropdownMenu, DropdownMenuTrigger } from \"../dropdown-menu\";\nimport { ContextMenu, ContextMenuTrigger } from \"../context-menu\";\nimport {\n MenuLookCheckboxItem,\n MenuLookContent,\n MenuLookContextCheckboxItem,\n MenuLookContextContent,\n MenuLookContextItem,\n MenuLookContextLabel,\n MenuLookContextSeparator,\n MenuLookContextSub,\n MenuLookContextSubContent,\n MenuLookContextSubTrigger,\n MenuLookItem,\n MenuLookLabel,\n MenuLookSeparator,\n MenuLookSub,\n MenuLookSubContent,\n MenuLookSubTrigger,\n type MenuLookCheckboxItemProps,\n type MenuLookItemProps,\n type MenuLookLabelProps,\n type MenuLookSubContentProps,\n type MenuLookSubTriggerProps,\n} from \"../menu-look\";\nimport { ItemMenuDrawer } from \"./ItemMenuDrawer\";\nimport { useItemMenuHost } from \"./host\";\nimport { runCommand, runToggle } from \"./run-entry\";\nimport {\n isCheckbox,\n isCommand,\n isLink,\n isSubmenu,\n resolveItemMenuConfig,\n type ItemContextMenuProps,\n type ItemMenuConfig,\n type ItemMenuEntry,\n type ItemMenuProps,\n type ItemMenuSection,\n} from \"./types\";\nimport type { ItemToastPromise } from \"./host\";\n\n// ── The two menus, one look ─────────────────────────────────────────────────\n// The \"…\" (dropdown) and the right-click (context menu) draw the SAME rows: the one menu look\n// (`../menu-look`, Arman 2026-10-23: \"the IDENTICAL dropdown ... for size and style\"). One renderer,\n// two Radix families underneath.\n\ninterface MenuFamily {\n Item: React.ComponentType<MenuLookItemProps>;\n CheckboxItem: React.ComponentType<MenuLookCheckboxItemProps>;\n Sub: React.ComponentType<{ children?: ReactNode }>;\n SubTrigger: React.ComponentType<MenuLookSubTriggerProps>;\n SubContent: React.ComponentType<MenuLookSubContentProps>;\n Separator: React.ComponentType;\n Label: React.ComponentType<MenuLookLabelProps>;\n}\n\nconst dropdownFamily: MenuFamily = {\n Item: MenuLookItem,\n CheckboxItem: MenuLookCheckboxItem,\n Sub: MenuLookSub,\n SubTrigger: MenuLookSubTrigger,\n SubContent: MenuLookSubContent,\n Separator: MenuLookSeparator,\n Label: MenuLookLabel,\n};\n\nconst contextFamily = {\n Item: MenuLookContextItem,\n CheckboxItem: MenuLookContextCheckboxItem,\n Sub: MenuLookContextSub,\n SubTrigger: MenuLookContextSubTrigger,\n SubContent: MenuLookContextSubContent,\n Separator: MenuLookContextSeparator,\n Label: MenuLookContextLabel,\n} as unknown as MenuFamily;\n\n// ── Action dispatch — shared with any host right-click converter ────────────\n// Lives in run-entry.ts so toast.promise / fire-and-forget semantics cannot\n// drift between the kebab dropdown and the universal right-click menu.\n\n// ── Shared leaf content ─────────────────────────────────────────────────────\n\n/** An entry's row, in the menu look's words: icon, label (hover text), why-disabled line, badge, key. */\nfunction entryRow(entry: ItemMenuEntry, { showShortcut = true }: { showShortcut?: boolean } = {}) {\n const Icon = entry.icon;\n const shortcut =\n showShortcut && (isCommand(entry) || isCheckbox(entry))\n ? (entry.shortcut ?? entry.shortcutKey?.toUpperCase())\n : undefined;\n return {\n // A destructive row's glyph takes the row's danger tone (menu-look.css); others keep their own color.\n icon: Icon ? <Icon className={isCommand(entry) && entry.tone === \"destructive\" ? undefined : entry.iconClassName} /> : undefined,\n label: entry.label,\n labelTitle: entry.description,\n // The only second line an entry draws is why it is disabled; `description` is hover text\n // (Arman, 2026-10-14: no \"novels\" in menus).\n description: entry.disabled && entry.disabledReason ? entry.disabledReason : undefined,\n badge: entry.badge,\n shortcut,\n };\n}\n\n// ── Recursive section renderer (desktop dropdown + context) ─────────────────\n\nfunction MenuSections({\n family,\n sections,\n onCloseRequest,\n}: {\n family: MenuFamily;\n sections: ItemMenuSection[];\n /** Closes the menu (used by link clicks; commands close via Radix default). */\n onCloseRequest: () => void;\n}) {\n const visibleSections = sections\n .map((s) => ({ ...s, items: s.items.filter((e) => !e.hidden) }))\n .filter((s) => s.items.length > 0);\n\n return (\n <>\n {visibleSections.map((section, sIdx) => (\n <Fragment key={section.id ?? section.label ?? sIdx}>\n {sIdx > 0 && <family.Separator />}\n {section.label && <family.Label>{section.label}</family.Label>}\n {section.items.map((entry) => (\n <MenuLeaf\n key={entry.id}\n family={family}\n entry={entry}\n onCloseRequest={onCloseRequest}\n />\n ))}\n </Fragment>\n ))}\n </>\n );\n}\n\nfunction keepCanonicalPaletteInteraction(event: CustomEvent<{ originalEvent: Event }>) {\n const target = event.detail.originalEvent.target;\n if (target instanceof Element && target.closest(\"[data-canonical-alchemy-submenu]\")) event.preventDefault();\n}\n\nfunction MenuLeaf({\n family,\n entry,\n onCloseRequest,\n}: {\n family: MenuFamily;\n entry: ItemMenuEntry;\n onCloseRequest: () => void;\n}) {\n const toastPromise = useItemMenuHost()?.toastPromise;\n if (isSubmenu(entry)) {\n return (\n <family.Sub>\n <family.SubTrigger {...entryRow(entry, { showShortcut: false })} disabled={entry.disabled} onPointerLeave={(event) => {\n if (entry.renderContent && event.relatedTarget instanceof Element && event.relatedTarget.closest(\"[data-canonical-alchemy-submenu]\")) event.preventDefault();\n }} />\n <family.SubContent onFocusOutside={keepCanonicalPaletteInteraction} onPointerDownOutside={keepCanonicalPaletteInteraction} fit={entry.renderContent ? \"content\" : \"menu\"}>\n {entry.renderContent ? entry.renderContent(onCloseRequest) : <MenuSections\n family={family}\n sections={entry.sections}\n onCloseRequest={onCloseRequest}\n />}\n </family.SubContent>\n </family.Sub>\n );\n }\n\n if (isCheckbox(entry)) {\n return (\n <family.CheckboxItem\n {...entryRow(entry)}\n checked={entry.checked}\n disabled={entry.disabled}\n onSelect={(e) => e.preventDefault()} // stay open\n onCheckedChange={(next) => runToggle(entry, next)}\n />\n );\n }\n\n if (isLink(entry)) {\n return (\n <family.Item\n {...entryRow(entry)}\n disabled={entry.disabled}\n href={entry.href}\n target={entry.target}\n linkProps={{ onClick: onCloseRequest }}\n />\n );\n }\n\n // command\n return (\n <family.Item\n {...entryRow(entry)}\n disabled={entry.disabled}\n destructive={entry.tone === \"destructive\"}\n onSelect={() => runCommand(entry, toastPromise)}\n />\n );\n}\n\n// ── Single-key shortcut handling ────────────────────────────────────────────\n\nfunction makeShortcutHandler(\n config: ItemMenuConfig,\n close: () => void,\n toastPromise?: ItemToastPromise,\n): (event: React.KeyboardEvent) => void {\n return (event) => {\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n if (event.key.length !== 1) return;\n const key = event.key.toLowerCase();\n // Top-level entries only — submenus handle their own keys when open.\n const entries = config.sections\n .flatMap((s) => s.items)\n .filter((e) => !e.hidden && !e.disabled);\n const match = entries.find(\n (e) =>\n (isCommand(e) || isCheckbox(e)) && e.shortcutKey?.toLowerCase() === key,\n );\n if (!match) return;\n event.preventDefault();\n event.stopPropagation();\n if (isCheckbox(match)) {\n runToggle(match, !match.checked); // stays open\n } else if (isCommand(match)) {\n runCommand(match, toastPromise); // sets pendingRename etc. before close\n close();\n }\n };\n}\n\nfunction RowAlchemyIcon(props: { className?: string | undefined }) {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden {...props}>\n {ALCHEMY_GLYPH_PATHS.portal.map((d, index) => <path key={index} d={d} />)}\n </svg>\n );\n}\nfunction hasVisibleEntry(config: ItemMenuConfig | null, id: string): boolean {\n const entries = config?.sections.flatMap((section) => section.items) ?? [];\n return entries.some((entry) =>\n entry.id === id\n ? !entry.hidden\n : isSubmenu(entry) && entry.sections.some((section) =>\n section.items.some((child) => child.id === id && !child.hidden),\n ),\n );\n}\nconst containsDestructiveAction = (items: ItemMenuEntry[]): boolean => items.some((item) =>\n (isCommand(item) && item.tone === \"destructive\") || (isSubmenu(item) && item.sections.some((section) => containsDestructiveAction(section.items))),\n);\n\n/** The transfer session stays mounted in the row; only its canonical palette portals here. */\nfunction RowAlchemySubmenuContent({ onClose, restoreFocus }: { onClose: () => void; restoreFocus: () => void }) {\n const alchemy = useMatrxTableRowAlchemy();\n const target = useRef<HTMLDivElement>(null);\n const closeRef = useRef(onClose);\n const focusRef = useRef(restoreFocus);\n useEffect(() => { focusRef.current = restoreFocus; }, [restoreFocus]);\n useEffect(() => { closeRef.current = onClose; }, [onClose]);\n const mountMenu = alchemy?.mountMenu;\n useEffect(() => {\n mountMenu?.(target.current, () => closeRef.current(), () => focusRef.current());\n return () => mountMenu?.(null);\n }, [mountMenu]);\n return <div ref={target} data-canonical-alchemy-submenu aria-label=\"Alchemy output options\" onKeyDown={(event) => {\n // The embedded canonical palette uses native controls, not MenuItems.\n // Let Tab reach those controls instead of Radix's menu-only suppression.\n if (event.key === \"Tab\") event.stopPropagation();\n }} />;\n}\n\n// ── ItemMenu (trigger-anchored dropdown / drawer) ───────────────────────────\n\n/** How long the pointer rests on the trigger before the real menu mounts under it. */\nconst ARM_ON_HOVER_MS = 150;\n\nexport function ItemMenu({\n config,\n children,\n align = \"end\",\n side,\n open: openProp,\n onOpenChange,\n onCloseAutoFocus,\n presentation = \"auto\",\n}: ItemMenuProps) {\n const toastPromise = useItemMenuHost()?.toastPromise;\n const rowAlchemy = useMatrxTableRowAlchemy();\n const rowControls = useMatrxTableRowControls();\n const restoreTargetRef = useRef<HTMLElement | null>(null);\n const dropdownTriggerRef = useRef<HTMLButtonElement | null>(null);\n useEffect(() => { rowAlchemy?.activate(); }, [rowAlchemy]);\n const isMobile = useIsMobile();\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : uncontrolledOpen;\n // Resolve while open so controlled open (whole-row click) and trigger open\n // share one path — no setState-during-render, no empty first frame.\n const baseConfig = open ? resolveItemMenuConfig(config) : null;\n const includeAlchemy = Boolean(rowAlchemy?.ready)\n && !hasVisibleEntry(baseConfig, \"alchemy\");\n const alchemyItem: ItemMenuEntry | null = rowAlchemy ? {\n kind: \"submenu\",\n id: \"alchemy\",\n label: \"Alchemy\",\n icon: RowAlchemyIcon,\n disabled: rowAlchemy.copy.disabled,\n sections: [],\n renderContent: (onClose) => <RowAlchemySubmenuContent onClose={onClose} restoreFocus={() => (dropdownTriggerRef.current ?? restoreTargetRef.current)?.focus()} />,\n } : null;\n const normalSections = baseConfig?.sections.map((section, index) => ({ section, index }))\n .filter(({ section }) => section.id !== \"danger\" && !containsDestructiveAction(section.items)) ?? [];\n const targetSection = (normalSections.find(({ section }) => !section.label) ?? normalSections[0])?.index;\n const injectedRowItems: ItemMenuEntry[] = [\n ...(rowControls?.beginEdit && !hasVisibleEntry(baseConfig, \"table-edit-row\") ? [{ id: \"table-edit-row\", label: \"Edit row\", onSelect: rowControls.beginEdit }] : []),\n ...(rowControls?.saveEdits && !hasVisibleEntry(baseConfig, \"table-save-row\") ? [{ id: \"table-save-row\", label: \"Save changes\", onSelect: rowControls.saveEdits }] : []),\n ...(rowControls?.cancelEdits && !hasVisibleEntry(baseConfig, \"table-discard-row\") ? [{ id: \"table-discard-row\", label: \"Discard changes\", onSelect: rowControls.cancelEdits }] : []),\n ...(alchemyItem && includeAlchemy ? [alchemyItem] : []),\n ];\n const resolved: ItemMenuConfig | null = baseConfig && injectedRowItems.length > 0 ? {\n ...baseConfig,\n sections: targetSection !== undefined\n ? baseConfig.sections.map((section, index) => index === targetSection ? { ...section, items: [...section.items, ...injectedRowItems] } : section)\n : [{ id: \"actions\", items: injectedRowItems }, ...baseConfig.sections],\n } : baseConfig;\n // A LONG MENU SAYS SO, IN WORDS (FIX-Q13): the panel declares its overflow — the menu look's\n // \"More actions below\" bar (`MenuLookContent moreBelowLabel`), never a fade that smears Delete.\n\n const handleOpenChange = (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n };\n\n const mode =\n presentation === \"auto\" ? (isMobile ? \"drawer\" : \"dropdown\") : presentation;\n\n // ── THE DROPDOWN MOUNTS ON FIRST INTENT ──────────────────────────────────\n //\n // A mounted Radix DropdownMenu listens to EVERY keydown on the document\n // (its keyboard-vs-pointer tracking), open or not. A list of 800 rows held\n // 800 of them: typing in a note beside the Notes sidebar paid 647ms of\n // listener work over 240 keystrokes (2026-10-10). Until the trigger is\n // hovered, focused or pressed it is the bare trigger; the first intent mounts\n // the real menu (a press opens it in the same gesture), and it stays mounted.\n const [armed, setArmed] = useState(false);\n const refocusOnArmRef = useRef(false);\n const armTimerRef = useRef<number | undefined>(undefined);\n useEffect(() => () => window.clearTimeout(armTimerRef.current), []);\n const live = armed || open;\n useEffect(() => {\n if (!armed || !refocusOnArmRef.current) return;\n // Mounting the menu replaced the trigger element; keep keyboard focus on it.\n refocusOnArmRef.current = false;\n dropdownTriggerRef.current?.focus();\n }, [armed]);\n\n if (mode === \"drawer\") {\n return (\n <>\n <Slot\n onClick={(e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.currentTarget instanceof HTMLElement) restoreTargetRef.current = e.currentTarget;\n handleOpenChange(true);\n }}\n >\n {children}\n </Slot>\n {resolved && (\n <ItemMenuDrawer\n open={open}\n onOpenChange={handleOpenChange}\n config={resolved}\n onCommand={(entry) => isCommand(entry) && runCommand(entry, toastPromise)}\n onToggle={(entry, next) =>\n isCheckbox(entry) && runToggle(entry, next)\n }\n />\n )}\n </>\n );\n }\n\n if (!live) {\n return (\n <Slot\n data-item-menu-trigger=\"idle\"\n onPointerEnter={() => {\n // Hover INTENT, not hover: mounting the real trigger swaps the button's\n // DOM node, and a press that arrives in the same few milliseconds as the\n // pointer (automation, a fast tap) is dispatched at the node that was just\n // removed — React never sees it and the click does nothing. A press inside\n // the delay takes the pointerdown path below, on the live node.\n window.clearTimeout(armTimerRef.current);\n armTimerRef.current = window.setTimeout(() => setArmed(true), ARM_ON_HOVER_MS);\n }}\n onPointerLeave={() => window.clearTimeout(armTimerRef.current)}\n onFocus={() => {\n refocusOnArmRef.current = true;\n setArmed(true);\n }}\n onPointerDown={(e: ReactPointerEvent) => {\n // A press with no hover first (touch-like input, automation): mount\n // and open in the same gesture, as Radix's own trigger would.\n if (e.button !== 0 || e.ctrlKey) return;\n e.preventDefault();\n setArmed(true);\n handleOpenChange(true);\n }}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <DropdownMenu open={open} onOpenChange={handleOpenChange} modal={false}>\n <DropdownMenuTrigger ref={dropdownTriggerRef} asChild>{children}</DropdownMenuTrigger>\n {resolved && (\n <MenuLookContent\n onFocusOutside={keepCanonicalPaletteInteraction}\n onPointerDownOutside={keepCanonicalPaletteInteraction}\n align={align}\n {...(side ? { side } : {})}\n // A rich menu (a full record-action registry is 20+ entries) is taller than a short\n // viewport: the look caps it at the room Radix measured and the rows scroll inside it.\n collisionPadding={12}\n moreBelowLabel=\"More actions below\"\n {...(onCloseAutoFocus ? { onCloseAutoFocus } : {})}\n onKeyDown={makeShortcutHandler(resolved, () =>\n handleOpenChange(false),\n toastPromise)}\n >\n {resolved.header?.title && (\n <MenuLookLabel description={resolved.header.description}>{resolved.header.title}</MenuLookLabel>\n )}\n <MenuSections\n family={dropdownFamily}\n sections={resolved.sections}\n onCloseRequest={() => handleOpenChange(false)}\n />\n </MenuLookContent>\n )}\n </DropdownMenu>\n );\n}\n// A record's menu is never a route header's phone primary: RouteHeader sends it\n// to the shell's ⋮ sheet instead of drawing a second overflow beside it\n// (`isMenuAction` in features/shell/components/header/route-header-layout.tsx).\nItemMenu.routeHeaderMenu = true as const;\n\n// ── ItemContextMenu (right-click anchored) ──────────────────────────────────\n// The host's universal right-click menu when one is provided\n// (`ItemMenuHostProvider` — the website and chat mount the v3 menu, which adds\n// Copy, agents, Attach To and Share around the row's own config). Without a\n// host, the same config opens in design-system's ContextMenu: right-click is\n// never missing, only less rich.\n\nexport function ItemContextMenu(props: ItemContextMenuProps) {\n const host = useItemMenuHost();\n if (props.enabled === false) return <>{props.children}</>;\n const HostMenu = host?.ContextMenu;\n if (HostMenu) return <HostMenu {...props} />;\n return <DefaultItemContextMenu {...props} />;\n}\n\nfunction DefaultItemContextMenu({\n config,\n children,\n resolveItemOnOpen,\n onOpenChange,\n onCloseAutoFocus,\n}: ItemContextMenuProps) {\n const [resolved, setResolved] = useState<ItemMenuConfig | null>(null);\n const targetRef = useRef<HTMLElement | null>(null);\n return (\n <ContextMenu\n modal={false}\n onOpenChange={(open) => {\n if (open) {\n const item = resolveItemOnOpen?.(targetRef.current);\n setResolved(resolveItemMenuConfig(item?.config ?? config));\n }\n onOpenChange?.(open);\n }}\n >\n <ContextMenuTrigger\n asChild\n onContextMenu={(event) => {\n targetRef.current = event.target instanceof HTMLElement ? event.target : null;\n }}\n >\n {children}\n </ContextMenuTrigger>\n {resolved && (\n <MenuLookContextContent onCloseAutoFocus={onCloseAutoFocus}>\n {resolved.header?.title && (\n <MenuLookContextLabel description={resolved.header.description}>{resolved.header.title}</MenuLookContextLabel>\n )}\n <MenuSections family={contextFamily} sections={resolved.sections} onCloseRequest={() => onOpenChange?.(false)} />\n </MenuLookContextContent>\n )}\n </ContextMenu>\n );\n}\n\n// `config` may be a GETTER resolved only when the menu opens. Every list writes it inline\n// (`config={() => menuFor(row)}`), so the table compares it by what it returns, never by identity —\n// otherwise each host render redrew every row (/crm: 25 of 25 per checkbox tick).\ndeclareLazyDataProps(ItemMenu, [\"config\"]);\ndeclareLazyDataProps(ItemContextMenu, [\"config\"]);\n","\"use client\";\n\n/**\n * ItemMenuDrawer — mobile presentation for ItemMenu.\n *\n * A Vaul bottom sheet with iOS-style submenu drill-in: tapping a submenu pushes\n * a new view (slide-in-from-right), the back button pops it (slide-in-from-left).\n * Renders the same ItemMenuConfig the desktop dropdown/context menu use.\n *\n * Used internally by ItemMenu — not exported as a standalone primitive.\n */\n\nimport { useState } from \"react\";\nimport { ChevronLeftIcon as ChevronLeft, ChevronRightIcon as ChevronRight, CheckIcon } from \"../icons\";\nimport {\n Drawer,\n DrawerContent,\n DrawerTitle,\n} from \"../drawer\";\nimport { cn } from \"../cn\";\nimport {\n isCheckbox,\n isCommand,\n isLink,\n isSubmenu,\n type ItemMenuConfig,\n type ItemMenuEntry,\n type ItemMenuSection,\n type ItemMenuSubmenu,\n} from \"./types\";\n\ninterface ItemMenuDrawerProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n config: ItemMenuConfig;\n /** Runs a command entry (close-then-execute is handled by the caller). */\n onCommand: (entry: ItemMenuEntry) => void;\n /** Toggles a checkbox entry without closing the drawer. */\n onToggle: (entry: ItemMenuEntry, next: boolean) => void;\n}\n\n/** Walk a submenu `path` (entry ids) to the sections it points at. */\nfunction resolveSections(\n config: ItemMenuConfig,\n path: string[],\n): { sections: ItemMenuSection[]; title: string | null; renderContent?: ItemMenuSubmenu[\"renderContent\"] } {\n let sections = config.sections;\n let title: string | null = null;\n let renderContent: ItemMenuSubmenu[\"renderContent\"];\n for (const id of path) {\n const found = sections\n .flatMap((s) => s.items)\n .find((e) => e.id === id && isSubmenu(e));\n if (found && isSubmenu(found)) {\n sections = found.sections;\n title = found.label;\n renderContent = found.renderContent;\n } else {\n // Unknown id — defensively reset to root.\n return { sections: config.sections, title: null };\n }\n }\n return { sections, title, renderContent };\n}\n\nexport function ItemMenuDrawer({\n open,\n onOpenChange,\n config,\n onCommand,\n onToggle,\n}: ItemMenuDrawerProps) {\n const [path, setPath] = useState<string[]>([]);\n const [direction, setDirection] = useState<\"push\" | \"pop\">(\"push\");\n\n const { sections, title, renderContent } = resolveSections(config, path);\n const atRoot = path.length === 0;\n const headerTitle = atRoot ? config.header?.title : title;\n\n const push = (id: string) => {\n setDirection(\"push\");\n setPath((p) => [...p, id]);\n };\n const pop = () => {\n setDirection(\"pop\");\n setPath((p) => p.slice(0, -1));\n };\n\n const handleOpenChange = (next: boolean) => {\n if (!next) setPath([]);\n onOpenChange(next);\n };\n\n return (\n <Drawer open={open} onOpenChange={handleOpenChange}>\n <DrawerContent className=\"max-h-[80dvh] flex flex-col\">\n {/* Header — Back button when drilled in. DrawerTitle always present. */}\n {atRoot ? (\n headerTitle ? (\n <div className=\"flex-shrink-0 border-b border-border px-4 pb-3 pt-1\">\n <DrawerTitle className=\"text-center text-[15px] font-semibold\">\n {headerTitle}\n </DrawerTitle>\n {config.header?.description && (\n <p className=\"mt-1 text-center type-body text-muted-foreground\">\n {config.header.description}\n </p>\n )}\n </div>\n ) : (\n <DrawerTitle className=\"sr-only\">Options</DrawerTitle>\n )\n ) : (\n <div className=\"flex h-11 flex-shrink-0 items-center border-b border-border px-1\">\n <button\n type=\"button\"\n onClick={pop}\n aria-label=\"Back\"\n className=\"flex h-9 items-center gap-1 rounded-md px-2 text-sm text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <DrawerTitle className=\"flex-1 truncate pr-10 text-center text-[15px] font-semibold\">\n {headerTitle ?? \"Options\"}\n </DrawerTitle>\n </div>\n )}\n\n {/* Body — keyed by path so each view animates in. */}\n <div\n key={path.join(\"/\")}\n className={cn(\n \"flex-1 overflow-y-auto overscroll-contain py-2 pb-safe\",\n direction === \"push\"\n ? \"animate-in fade-in slide-in-from-right-8 duration-200\"\n : \"animate-in fade-in slide-in-from-left-8 duration-200\",\n )}\n >\n {renderContent?.(() => handleOpenChange(false))}\n {sections.map((section, sIdx) => {\n const visible = section.items.filter((e) => !e.hidden);\n if (visible.length === 0) return null;\n return (\n <div key={section.id ?? section.label ?? sIdx}>\n {sIdx > 0 && <div className=\"my-1 h-px bg-border\" />}\n {section.label && (\n <div className=\"px-4 pb-1 pt-2 type-secondary font-medium uppercase tracking-wide text-muted-foreground\">\n {section.label}\n </div>\n )}\n {visible.map((entry) => (\n <DrawerEntry\n key={entry.id}\n entry={entry}\n onCommand={onCommand}\n onToggle={onToggle}\n onDrill={() => push(entry.id)}\n onClose={() => handleOpenChange(false)}\n />\n ))}\n </div>\n );\n })}\n </div>\n </DrawerContent>\n </Drawer>\n );\n}\n\ninterface DrawerEntryProps {\n entry: ItemMenuEntry;\n onCommand: (entry: ItemMenuEntry) => void;\n onToggle: (entry: ItemMenuEntry, next: boolean) => void;\n onDrill: () => void;\n onClose: () => void;\n}\n\nfunction DrawerEntry({\n entry,\n onCommand,\n onToggle,\n onDrill,\n onClose,\n}: DrawerEntryProps) {\n const Icon = entry.icon;\n const destructive = isCommand(entry) && entry.tone === \"destructive\";\n const disabled = entry.disabled;\n\n const rowClass = cn(\n \"flex min-h-12 w-full items-center gap-3 px-4 text-left\",\n disabled\n ? \"opacity-50\"\n : \"active:bg-accent\",\n destructive && \"text-destructive\",\n );\n\n const content = (\n <>\n {Icon && (\n <Icon\n className={cn(\n \"h-[18px] w-[18px] shrink-0\",\n destructive\n ? \"text-destructive\"\n : entry.iconClassName ?? \"text-muted-foreground\",\n )}\n />\n )}\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate text-[15px]\" title={entry.description}>{entry.label}</span>\n {disabled && entry.disabledReason ? (\n <span className=\"truncate type-body text-muted-foreground\">{entry.disabledReason}</span>\n ) : null}\n </span>\n </>\n );\n\n if (isSubmenu(entry)) {\n return (\n <button type=\"button\" disabled={disabled} onClick={onDrill} className={rowClass}>\n {content}\n <ChevronRight className=\"h-5 w-5 shrink-0 text-muted-foreground\" />\n </button>\n );\n }\n\n if (isCheckbox(entry)) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => onToggle(entry, !entry.checked)}\n className={rowClass}\n >\n {content}\n {entry.checked && <CheckIcon className=\"h-5 w-5 shrink-0 text-primary\" />}\n </button>\n );\n }\n\n if (isLink(entry)) {\n return (\n <a\n href={entry.href}\n target={entry.target}\n rel={entry.target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n onClick={onClose}\n className={rowClass}\n >\n {content}\n </a>\n );\n }\n\n // command\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => {\n onClose();\n onCommand(entry);\n }}\n className={rowClass}\n >\n {content}\n </button>\n );\n}\n","\"use client\";\n\n/**\n * ItemRow — the reusable list row.\n *\n * - Full-width label with a right-edge mask fade (NO ellipsis) that deepens on\n * hover/focus/menu-open to clear the kebab (see `.item-row`/`.item-fade` in\n * design-system styles.css). Trailing indicators glide left in sync.\n * - Kebab is an absolute sibling (reserves no layout space) revealed on\n * hover/focus/menu-open, and always visible on touch.\n * - Right-click opens the SAME menu config (ItemContextMenu), disabled on touch.\n * - Inline rename: double-click the row, or a menu entry with `intent: \"rename\"`\n * (ItemRow swaps that entry's action for its own edit state and wins the\n * focus race via onCloseAutoFocus).\n *\n * The menu/rename schema lives in ./types; menus render via ./ItemMenu.\n */\n\nimport { useRef, useState } from \"react\";\nimport {\n ChevronDownIcon as ChevronDown,\n ChevronRightIcon as ChevronRight,\n MoreHorizontalIcon as MoreHorizontal,\n} from \"../icons\";\nimport { cn } from \"../cn\";\nimport { Button } from \"../controls/controls\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport { EditableLabel } from \"../editable-label\";\nimport { getTapTargetLinkComponent } from \"../tap-target/link\";\nimport { ItemMenu, ItemContextMenu } from \"./ItemMenu\";\nimport {\n isCommand,\n isSubmenu,\n resolveItemMenuConfig,\n type ItemMenuConfig,\n type ItemMenuConfigInput,\n type ItemMenuEntry,\n type ItemMenuSection,\n type ItemRowProps,\n type ItemRowSize,\n} from \"./types\";\n\nconst SIZE: Record<\n ItemRowSize,\n { row: string; text: string; kebab: string; icon: string; tone?: string }\n> = {\n // A nested sub-row (a conversation's helpers under it in the chat sidebar):\n // finer and quieter than its parent, so a tree reads at a glance.\n xs: {\n row: \"h-6\",\n text: \"text-xs\",\n kebab: \"h-5 w-5\",\n icon: \"h-3.5 w-3.5\",\n tone: \"text-muted-foreground\",\n },\n sm: {\n row: \"h-7\",\n text: \"text-[13px]\",\n kebab: \"h-5 w-5\",\n icon: \"h-3.5 w-3.5\",\n },\n md: { row: \"h-8\", text: \"text-sm\", kebab: \"h-6 w-6\", icon: \"h-4 w-4\" },\n lg: { row: \"h-10\", text: \"text-sm\", kebab: \"h-7 w-7\", icon: \"h-4 w-4\" },\n};\n\n/**\n * The trailing room a row keeps for its disclosure: the button (kebab size) + the 4px end inset +\n * a 4px gap, so the trailing meta (time) never touches the chevron. A disclosure row and a plain\n * sibling that passes `reserveDisclosure` keep the SAME room, so every row's meta ends on one edge.\n */\nconst DISCLOSURE_RESERVE: Record<ItemRowSize, number> = { xs: 32, sm: 32, md: 36, lg: 40 };\n\n/**\n * What reveals the kebab and the hover-only meta: pointer over the row, keyboard focus inside it,\n * its menu open, or a touch screen. Keyboard focus only — a clicked row keeps focus on its link, and\n * that must not pin its kebab and time on after the pointer leaves.\n */\nconst REVEAL_OPACITY =\n \"group-hover/item:opacity-100 group-has-[:focus-visible]/item:opacity-100 group-has-[[data-state=open]]/item:opacity-100 [@media(pointer:coarse)]:opacity-100\";\nconst REVEAL_DISPLAY =\n \"group-hover/item:inline group-has-[:focus-visible]/item:inline group-has-[[data-state=open]]/item:inline [@media(pointer:coarse)]:inline\";\n\n/**\n * Replace `intent: \"rename\"` command actions with the host's rename trigger —\n * or REMOVE them when this row has no `rename` prop at all.\n *\n * 🚨 The removal half is not tidiness. Without it, a row that renders a menu\n * carrying `intent: \"rename\"` but passes no `rename` handed the user a live\n * \"Rename\" row whose click set `pendingRenameRef`, flipped `editing`, and then\n * rendered the plain label again because `editing && rename` is false —\n * a control that looks clickable and does nothing (found by the LIVE-ITEM LAW,\n * 2026-09-11). `ctx.showRename === false` asks every consumer to remember;\n * this is the one place that KNOWS. Absent beats dead.\n */\nfunction mapRenameIntent(\n config: ItemMenuConfig,\n requestRename: (() => void) | null,\n): ItemMenuConfig {\n const mapEntry = (entry: ItemMenuEntry): ItemMenuEntry | null => {\n if (isSubmenu(entry)) {\n return { ...entry, sections: entry.sections.map(mapSection) };\n }\n if (isCommand(entry) && entry.intent === \"rename\") {\n return requestRename ? { ...entry, onSelect: requestRename } : null;\n }\n return entry;\n };\n const mapSection = (section: ItemMenuSection): ItemMenuSection => ({\n ...section,\n items: section.items\n .map(mapEntry)\n .filter((e): e is ItemMenuEntry => e !== null),\n });\n return { ...config, sections: config.sections.map(mapSection) };\n}\n\nexport function ItemRow({\n label,\n secondaryLabel,\n secondaryShare = \"half\",\n subtitle,\n actions,\n leadingControl,\n disclosure,\n reserveDisclosure = false,\n leading,\n trailing,\n trailingOnHover,\n active = false,\n disabled = false,\n href,\n onOpen,\n openInPlace = false,\n menu,\n rename,\n size = \"md\",\n indent,\n kebabAriaLabel,\n disableContextMenu = false,\n sourceFeature,\n surfaceName,\n entity,\n className,\n}: ItemRowProps) {\n const isMobile = useIsMobile();\n const [editing, setEditing] = useState(false);\n const pendingRenameRef = useRef(false);\n const sz = SIZE[size];\n\n const canRename = !!rename;\n const allowDoubleClick = canRename && rename.doubleClick !== false;\n\n // Wrap the menu so rename-intent entries drive ItemRow's edit state, and so\n // a static config is still resolved lazily (on open).\n const mappedMenu: ItemMenuConfigInput | undefined = menu\n ? () =>\n mapRenameIntent(\n resolveItemMenuConfig(menu),\n canRename\n ? () => {\n pendingRenameRef.current = true;\n }\n : null,\n )\n : undefined;\n\n // Radix returns focus to the trigger on close; when a rename was requested,\n // intercept it and move focus into the input instead (no focus tug-of-war).\n const handleCloseAutoFocus = (event: Event) => {\n if (pendingRenameRef.current) {\n pendingRenameRef.current = false;\n event.preventDefault();\n setEditing(true);\n }\n };\n\n const startInlineRename = () => {\n if (canRename) setEditing(true);\n };\n\n const labelNode =\n editing && rename ? (\n <EditableLabel\n activation=\"controlled\"\n editing\n onEditingChange={(next) => setEditing(next)}\n value={rename.value ?? label}\n onCommit={rename.onCommit}\n {...(rename.validate ? { validate: rename.validate } : {})}\n {...(rename.emptyFallback !== undefined ? { emptyFallback: rename.emptyFallback } : {})}\n {...(rename.maxLength !== undefined ? { maxLength: rename.maxLength } : {})}\n ariaLabel=\"Name\"\n className=\"flex-1\"\n inputClassName={cn(\"font-normal\", sz.text)}\n />\n ) : subtitle != null ? (\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className={cn(\"item-fade min-w-0\", sz.text)} title={label}>\n {label}\n </span>\n <span className=\"min-w-0 truncate type-secondary text-muted-foreground\" data-item-subtitle=\"\">\n {subtitle}\n </span>\n </span>\n ) : (\n <span className={cn(\"item-fade min-w-0 flex-1\", sz.text)} title={label}>\n {label}\n </span>\n );\n\n const primaryInner = (\n <>\n {leading != null && (\n <span className=\"flex shrink-0 items-center\">{leading}</span>\n )}\n {labelNode}\n {secondaryLabel && (\n // Clamped: a secondary value can be a sentence (a lineage edge's\n // \"140 cards - 1 section could not be covered …\"). Unclamped it pushed\n // the label out of the row (owner, 2026-10-04).\n <span\n className={cn(\n \"item-shift min-w-0 truncate type-secondary text-muted-foreground\",\n secondaryShare === \"third\" ? \"max-w-[33%]\" : \"max-w-[50%]\",\n )}\n title={secondaryLabel}\n >\n {secondaryLabel}\n </span>\n )}\n {(trailing != null || trailingOnHover != null) && (\n <span className=\"item-shift flex shrink-0 items-center gap-1 pr-0.5\">\n {trailing}\n {trailingOnHover != null && (\n <span className={cn(\"hidden\", REVEAL_DISPLAY)} data-item-trailing-hover=\"\">\n {trailingOnHover}\n </span>\n )}\n </span>\n )}\n </>\n );\n\n const twoLine = subtitle != null && !editing;\n const sideBySide = actions != null || leadingControl != null;\n\n // THE DISCLOSURE IS ON THE RIGHT (Arman, 2026-10-23): a real button outside the row's link, after\n // the label and the trailing indicators — never before the label. It glides with the trailing\n // indicators when the kebab shows, so the two never overlap.\n const disclosureButton = disclosure ? (\n <Button\n type=\"button\"\n variant=\"quiet\"\n data-item-disclosure=\"\"\n aria-expanded={disclosure.open}\n aria-label={disclosure.ariaLabel ?? `${disclosure.open ? \"Collapse\" : \"Expand\"} ${label}`}\n onClick={(e) => {\n e.stopPropagation();\n disclosure.onToggle();\n }}\n icon={disclosure.open ? <ChevronDown className={sz.icon} /> : <ChevronRight className={sz.icon} />}\n className=\"shrink-0\"\n >\n </Button>\n ) : null;\n const primaryClass = cn(\n \"flex min-w-0 items-center gap-1.5 rounded-lg px-2\",\n sideBySide ? \"flex-1\" : \"w-full\",\n twoLine ? \"min-h-11 py-1.5\" : sz.row,\n sz.text,\n \"outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring\",\n active ? \"font-medium text-primary\" : (sz.tone ?? \"text-foreground\"),\n );\n\n const indentStyle: React.CSSProperties | undefined =\n (indent && indent > 0) || ((disclosure || reserveDisclosure) && !sideBySide)\n ? {\n ...(indent && indent > 0 ? { paddingInlineStart: 8 + indent * 16 } : {}),\n // Room for the disclosure at the trailing edge (its box + the row's 4px end inset).\n ...((disclosure || reserveDisclosure) && !sideBySide ? { paddingInlineEnd: DISCLOSURE_RESERVE[size] } : {}),\n }\n : undefined;\n\n // Primary element: link (navigation), button (click), or div (editing/disabled).\n let primary: React.ReactNode;\n if (editing || disabled) {\n primary = (\n <div className={primaryClass} style={indentStyle} data-item-primary=\"\">\n {primaryInner}\n </div>\n );\n } else if (href) {\n // The host's registered link (`setTapTargetLinkComponent`, e.g. next/link), else a plain anchor.\n const RegisteredLink = getTapTargetLinkComponent();\n const Link = (RegisteredLink ?? \"a\") as unknown as React.ComponentType<React.AnchorHTMLAttributes<HTMLAnchorElement> & { href: string; prefetch?: boolean }>;\n primary = (\n <Link\n href={href}\n data-item-primary=\"\"\n // 🚨 A ROW NEVER PREFETCHES. next/link prefetches every link in view, so\n // a 20-row list (chat history) fired 20 background route renders on\n // page load (2026-10-09). A row is opened by a click; the click loads it.\n {...(RegisteredLink ? { prefetch: false } : {})}\n className={primaryClass}\n style={indentStyle}\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\n // Modifier / middle-click: native <a> opens a new tab/window.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return;\n // `openInPlace`: handle the click in-app and keep the page put. The\n // href stays for new-tab / copy-link affordances above.\n if (openInPlace) e.preventDefault();\n onOpen?.();\n // Without `openInPlace`, `onOpen` is a side effect only (close a\n // popover, etc.) — navigation stays on the Link href.\n }}\n onDoubleClick={\n allowDoubleClick\n ? (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n startInlineRename();\n }\n : undefined\n }\n >\n {primaryInner}\n </Link>\n );\n } else {\n primary = (\n <button\n type=\"button\"\n data-item-primary=\"\"\n className={cn(primaryClass, \"cursor-pointer text-left\")}\n style={indentStyle}\n onClick={onOpen}\n onDoubleClick={\n allowDoubleClick\n ? (e) => {\n e.preventDefault();\n e.stopPropagation();\n startInlineRename();\n }\n : undefined\n }\n >\n {primaryInner}\n </button>\n );\n }\n\n const kebab =\n mappedMenu && !editing ? (\n <ItemMenu\n config={mappedMenu}\n align=\"end\"\n onCloseAutoFocus={handleCloseAutoFocus}\n >\n <Button\n type=\"button\"\n variant=\"quiet\"\n aria-label={kebabAriaLabel ?? `Options for ${label}`}\n icon={<MoreHorizontal className={sz.icon} />}\n aria-haspopup=\"menu\"\n onClick={(e) => e.stopPropagation()}\n data-item-kebab=\"\"\n className={cn(\n \"shrink-0\",\n !sideBySide && \"absolute right-1 top-1/2 -translate-y-1/2\",\n // Hidden at rest (it would sit on the trailing meta); shown on hover, keyboard focus,\n // while its menu is open, and always on touch.\n \"opacity-0 transition-opacity data-[state=open]:opacity-100 focus-visible:opacity-100\",\n REVEAL_OPACITY,\n )}\n >\n </Button>\n </ItemMenu>\n ) : null;\n\n const row = (\n <div\n data-active={active || undefined}\n // The deep fade exists to clear the kebab; a menu-less row has none, so\n // its label keeps every pixel (touch used to fade it permanently).\n data-no-menu={mappedMenu && !sideBySide ? undefined : true}\n className={cn(\n \"item-row group/item relative rounded-lg transition-colors\",\n sideBySide && \"flex items-center\",\n !active && \"hover:bg-accent/60\",\n active && \"bg-primary/10 text-primary-ink\",\n className,\n )}\n >\n {leadingControl != null ? (\n <span className=\"flex shrink-0 items-center pl-2\" data-item-leading-control=\"\">\n {leadingControl}\n </span>\n ) : null}\n {primary}\n\n {!sideBySide && disclosureButton ? (\n <span\n className=\"item-shift absolute inset-y-0 right-1 flex items-center\"\n data-item-disclosure-slot=\"\"\n >\n {disclosureButton}\n </span>\n ) : null}\n {!sideBySide && kebab}\n {/* The actions wrapper adds NO gap or padding: tap buttons space themselves (tap-target guard\n rules 3 and 4 flag a wrapper that adds space around one); a plain (non-tap) child gets its own\n horizontal margin from the wrapper's child selector below. */}\n {sideBySide && (actions != null || kebab || disclosureButton) ? (\n <span\n className=\"flex shrink-0 items-center [&>:not(.matrx-tap-target,.matrx-alchemy)]:mx-0.5\"\n data-item-actions=\"\"\n >\n {actions}\n {disclosureButton}\n {kebab}\n </span>\n ) : null}\n </div>\n );\n\n if (!mappedMenu || disableContextMenu) return row;\n\n return (\n <ItemContextMenu\n config={mappedMenu}\n // Forwarded, not invented. `entity` is what turns Attach To and Share on\n // in the v3 menu; a row that omits it ships a menu missing two doors the\n // platform already owns. `sourceFeature` is REQUIRED rather than\n // defaulted: it used to be hardcoded `\"files\"` inside ItemContextMenu, a\n // confident lie on every non-file row, and `SourceFeature` is a closed\n // registry with no generic member to hide behind — so the compiler makes\n // each row name itself instead.\n sourceFeature={sourceFeature}\n surfaceName={surfaceName}\n entity={entity}\n enabled={!isMobile && !editing}\n onCloseAutoFocus={handleCloseAutoFocus}\n // The v3 context menu is not a Radix content, so `onCloseAutoFocus` never fires\n // there: a Rename picked from the right-click menu set the pending flag and\n // nothing ever opened the editor. Its close is the signal instead.\n onOpenChange={(open) => {\n if (!open && pendingRenameRef.current) {\n pendingRenameRef.current = false;\n setTimeout(() => setEditing(true), 0);\n }\n }}\n >\n {row}\n </ItemContextMenu>\n );\n}\n"],"mappings":"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","names":["Fragment","useState","jsx","Fragment","jsx","jsxs","useState","useRef","useState","useIsMobile","Fragment","jsx","jsxs","useIsMobile","useState","useRef"]}