@ai-matrx/design-system 0.86.332 → 0.86.334

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 (140) hide show
  1. package/CHANGELOG.md +28 -2
  2. package/dist/auth-gate-dialog.js +4 -4
  3. package/dist/carousel.js +18 -18
  4. package/dist/{chunk-MVGMI6UZ.js → chunk-3MQMVPKO.js} +5 -5
  5. package/dist/{chunk-2WL2SGKL.js → chunk-677JS6TX.js} +24 -10
  6. package/dist/chunk-677JS6TX.js.map +1 -0
  7. package/dist/{chunk-TBDMTCRW.js → chunk-6YZMGSQY.js} +10 -10
  8. package/dist/{chunk-OFJ5LGBU.js → chunk-7NEVJKDZ.js} +8 -8
  9. package/dist/{chunk-XTNAKJSH.js → chunk-B3LDW3IQ.js} +2 -2
  10. package/dist/{chunk-VTJWQPYR.js → chunk-BM2YYBUO.js} +5 -5
  11. package/dist/{chunk-FTZCPGTH.js → chunk-CFCWQDGC.js} +4 -4
  12. package/dist/{chunk-CN7C4KQB.js → chunk-CH2NWSES.js} +2 -2
  13. package/dist/{chunk-CJCUD62M.js → chunk-CSSD6NS4.js} +5 -5
  14. package/dist/{chunk-W3QSRJ3O.js → chunk-E4GS5QH7.js} +7 -7
  15. package/dist/{chunk-O4KANICE.js → chunk-FRJ4PPA2.js} +5 -5
  16. package/dist/{chunk-4PCLJAW2.js → chunk-FXT7PZAF.js} +5 -14
  17. package/dist/chunk-FXT7PZAF.js.map +1 -0
  18. package/dist/{chunk-D45XDOJS.js → chunk-GHPUO3O7.js} +2 -2
  19. package/dist/{chunk-RPUC5MNH.js → chunk-GLZJ7WZK.js} +3 -3
  20. package/dist/{chunk-VKWQTSB6.js → chunk-HEFTQUJ5.js} +6 -6
  21. package/dist/{chunk-KWBYKUKP.js → chunk-J6637L6D.js} +4 -4
  22. package/dist/chunk-KGW373MK.js +21 -0
  23. package/dist/chunk-KGW373MK.js.map +1 -0
  24. package/dist/{chunk-5LT34PFX.js → chunk-MEJVHDYJ.js} +18 -18
  25. package/dist/{chunk-PPB52S7F.js → chunk-MFUNGDHO.js} +7 -7
  26. package/dist/{chunk-LCPHFONA.js → chunk-MIJMP4WI.js} +5 -5
  27. package/dist/{chunk-XREKZXAL.js → chunk-SMJGESH7.js} +6 -6
  28. package/dist/{chunk-SNHCBHBE.js → chunk-U24MOJWK.js} +4 -4
  29. package/dist/{chunk-DO6G4EKJ.js → chunk-UWTODOMD.js} +2 -2
  30. package/dist/{chunk-BQR4N24F.js → chunk-VLLUUOYJ.js} +4 -4
  31. package/dist/{chunk-FD6V6JBN.js → chunk-VV6WZTH5.js} +8 -8
  32. package/dist/{chunk-LVM7XZRJ.js → chunk-WQ2QCMMA.js} +4 -4
  33. package/dist/{chunk-57OD2WTY.js → chunk-X6ZRHJQP.js} +6 -6
  34. package/dist/{chunk-PLFWDUJW.js → chunk-XEXSZBXV.js} +3 -3
  35. package/dist/{chunk-JSXNITMG.js → chunk-YC5GAO35.js} +2 -2
  36. package/dist/{chunk-5TF2AFDM.js → chunk-ZCRPESQX.js} +4 -4
  37. package/dist/{chunk-5IKQ6RU4.js → chunk-ZOQ2XKXF.js} +9 -9
  38. package/dist/clipboard-fallback-dialog.js +10 -10
  39. package/dist/controls.js +15 -15
  40. package/dist/data-table/data-row-inspector.js +15 -14
  41. package/dist/data-table/data-row-window.js +20 -19
  42. package/dist/data-table/index.cjs +16 -12
  43. package/dist/data-table/index.cjs.map +1 -1
  44. package/dist/data-table/index.js +37 -36
  45. package/dist/data-table/index.js.map +1 -1
  46. package/dist/data-table/layered-filter-builder.js +4 -4
  47. package/dist/data-table/pagination.js +8 -8
  48. package/dist/data-table/uuid-cell.js +8 -8
  49. package/dist/desktop.js +22 -22
  50. package/dist/email-input-dialog.js +7 -7
  51. package/dist/index.cjs +590 -397
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +120 -10
  54. package/dist/index.d.ts +120 -10
  55. package/dist/index.js +519 -348
  56. package/dist/index.js.map +1 -1
  57. package/dist/intro-stage.js +3 -3
  58. package/dist/item.cjs +33 -17
  59. package/dist/item.cjs.map +1 -1
  60. package/dist/item.d.cts +7 -1
  61. package/dist/item.d.ts +7 -1
  62. package/dist/item.js +32 -30
  63. package/dist/item.js.map +1 -1
  64. package/dist/lite-table.js +10 -10
  65. package/dist/menu-look.js +3 -3
  66. package/dist/record-list.cjs +16 -2
  67. package/dist/record-list.cjs.map +1 -1
  68. package/dist/record-list.d.cts +7 -1
  69. package/dist/record-list.d.ts +7 -1
  70. package/dist/record-list.js +13 -13
  71. package/dist/sandbox-gate-dialog.js +8 -8
  72. package/dist/scope-mismatch-dialog.js +7 -7
  73. package/dist/settings.cjs +16 -12
  74. package/dist/settings.cjs.map +1 -1
  75. package/dist/settings.js +20 -19
  76. package/dist/settings.js.map +1 -1
  77. package/dist/site-icon.js +2 -2
  78. package/dist/swipe-deck.js +1 -1
  79. package/dist/tap-shortcut.cjs +40 -0
  80. package/dist/tap-shortcut.cjs.map +1 -0
  81. package/dist/tap-shortcut.d.cts +13 -0
  82. package/dist/tap-shortcut.d.ts +13 -0
  83. package/dist/tap-shortcut.js +10 -0
  84. package/dist/tap-shortcut.js.map +1 -0
  85. package/dist/tap-target/ai-buttons.cjs +16 -12
  86. package/dist/tap-target/ai-buttons.cjs.map +1 -1
  87. package/dist/tap-target/ai-buttons.js +4 -3
  88. package/dist/tap-target/ai-buttons.js.map +1 -1
  89. package/dist/tap-target/buttons.cjs +16 -12
  90. package/dist/tap-target/buttons.cjs.map +1 -1
  91. package/dist/tap-target/buttons.d.cts +3 -5
  92. package/dist/tap-target/buttons.d.ts +3 -5
  93. package/dist/tap-target/buttons.js +4 -3
  94. package/dist/tap-target.cjs +16 -12
  95. package/dist/tap-target.cjs.map +1 -1
  96. package/dist/tap-target.d.cts +5 -7
  97. package/dist/tap-target.d.ts +5 -7
  98. package/dist/tap-target.js +6 -4
  99. package/dist/text-input-dialog.js +10 -10
  100. package/dist/thumbnail-grid.js +2 -2
  101. package/dist/transcript-scroll-nav.cjs +16 -12
  102. package/dist/transcript-scroll-nav.cjs.map +1 -1
  103. package/dist/transcript-scroll-nav.js +2 -1
  104. package/dist/transcript-scroll-nav.js.map +1 -1
  105. package/dist/value-prompts-dialog.js +5 -5
  106. package/dist/writing-field.cjs +16 -12
  107. package/dist/writing-field.cjs.map +1 -1
  108. package/dist/writing-field.js +21 -20
  109. package/dist/writing-field.js.map +1 -1
  110. package/package.json +12 -2
  111. package/dist/chunk-2WL2SGKL.js.map +0 -1
  112. package/dist/chunk-4PCLJAW2.js.map +0 -1
  113. /package/dist/{chunk-MVGMI6UZ.js.map → chunk-3MQMVPKO.js.map} +0 -0
  114. /package/dist/{chunk-TBDMTCRW.js.map → chunk-6YZMGSQY.js.map} +0 -0
  115. /package/dist/{chunk-OFJ5LGBU.js.map → chunk-7NEVJKDZ.js.map} +0 -0
  116. /package/dist/{chunk-XTNAKJSH.js.map → chunk-B3LDW3IQ.js.map} +0 -0
  117. /package/dist/{chunk-VTJWQPYR.js.map → chunk-BM2YYBUO.js.map} +0 -0
  118. /package/dist/{chunk-FTZCPGTH.js.map → chunk-CFCWQDGC.js.map} +0 -0
  119. /package/dist/{chunk-CN7C4KQB.js.map → chunk-CH2NWSES.js.map} +0 -0
  120. /package/dist/{chunk-CJCUD62M.js.map → chunk-CSSD6NS4.js.map} +0 -0
  121. /package/dist/{chunk-W3QSRJ3O.js.map → chunk-E4GS5QH7.js.map} +0 -0
  122. /package/dist/{chunk-O4KANICE.js.map → chunk-FRJ4PPA2.js.map} +0 -0
  123. /package/dist/{chunk-D45XDOJS.js.map → chunk-GHPUO3O7.js.map} +0 -0
  124. /package/dist/{chunk-RPUC5MNH.js.map → chunk-GLZJ7WZK.js.map} +0 -0
  125. /package/dist/{chunk-VKWQTSB6.js.map → chunk-HEFTQUJ5.js.map} +0 -0
  126. /package/dist/{chunk-KWBYKUKP.js.map → chunk-J6637L6D.js.map} +0 -0
  127. /package/dist/{chunk-5LT34PFX.js.map → chunk-MEJVHDYJ.js.map} +0 -0
  128. /package/dist/{chunk-PPB52S7F.js.map → chunk-MFUNGDHO.js.map} +0 -0
  129. /package/dist/{chunk-LCPHFONA.js.map → chunk-MIJMP4WI.js.map} +0 -0
  130. /package/dist/{chunk-XREKZXAL.js.map → chunk-SMJGESH7.js.map} +0 -0
  131. /package/dist/{chunk-SNHCBHBE.js.map → chunk-U24MOJWK.js.map} +0 -0
  132. /package/dist/{chunk-DO6G4EKJ.js.map → chunk-UWTODOMD.js.map} +0 -0
  133. /package/dist/{chunk-BQR4N24F.js.map → chunk-VLLUUOYJ.js.map} +0 -0
  134. /package/dist/{chunk-FD6V6JBN.js.map → chunk-VV6WZTH5.js.map} +0 -0
  135. /package/dist/{chunk-LVM7XZRJ.js.map → chunk-WQ2QCMMA.js.map} +0 -0
  136. /package/dist/{chunk-57OD2WTY.js.map → chunk-X6ZRHJQP.js.map} +0 -0
  137. /package/dist/{chunk-PLFWDUJW.js.map → chunk-XEXSZBXV.js.map} +0 -0
  138. /package/dist/{chunk-JSXNITMG.js.map → chunk-YC5GAO35.js.map} +0 -0
  139. /package/dist/{chunk-5TF2AFDM.js.map → chunk-ZCRPESQX.js.map} +0 -0
  140. /package/dist/{chunk-5IKQ6RU4.js.map → chunk-ZOQ2XKXF.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/design-system",
3
- "version": "0.86.332",
3
+ "version": "0.86.334",
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": {
@@ -679,6 +679,16 @@
679
679
  "types": "./dist/record-id-format.d.cts",
680
680
  "default": "./dist/record-id-format.cjs"
681
681
  }
682
+ },
683
+ "./tap-shortcut": {
684
+ "import": {
685
+ "types": "./dist/tap-shortcut.d.ts",
686
+ "default": "./dist/tap-shortcut.js"
687
+ },
688
+ "require": {
689
+ "types": "./dist/tap-shortcut.d.cts",
690
+ "default": "./dist/tap-shortcut.cjs"
691
+ }
682
692
  }
683
693
  },
684
694
  "dependencies": {
@@ -766,5 +776,5 @@
766
776
  ],
767
777
  "layer": 2
768
778
  },
769
- "gitHead": "24afe9d748196cdcb55580d0f81c5cb1e1067395"
779
+ "gitHead": "e9d7fb471faed968ff24ed0cf3d2aef2a5cdd3b6"
770
780
  }
@@ -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 /** Min width of the dropdown content. Default \"12rem\". */\n contentMinWidth?: string | 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 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) → Radix DropdownMenu, modal={false}\n * - right-click (wraps a surface) → the host's right-click menu\n * (`ItemMenuHostProvider`; the\n * website/chat mount v3), else\n * design-system's ContextMenu\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, useCallback, useEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from \"react\";\nimport { useScrollFade } from \"../use-scroll-fade\";\nimport { ChevronDownIcon as ChevronDown } from \"../icons\";\nimport { ALCHEMY_GLYPH_PATHS } from \"../content-transfer/icon\";\nimport { declareLazyDataProps, useMatrxTableRowAlchemy, useMatrxTableRowControls } from \"../table-host/host\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cn } from \"../cn\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n DropdownMenuShortcut,\n} from \"../dropdown-menu\";\nimport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuCheckboxItem,\n ContextMenuSub,\n ContextMenuSubTrigger,\n ContextMenuSubContent,\n ContextMenuSeparator,\n ContextMenuLabel,\n ContextMenuShortcut,\n} from \"../context-menu\";\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// ── Radix family adapter ────────────────────────────────────────────────────\n// One renderer, two component sets. Force z-[9999] on context content so menus\n// opened inside floating WindowPanels (z >= 1000) layer above the window.\n\ninterface MenuFamily {\n Item: React.ComponentType<{\n disabled?: boolean | undefined;\n onSelect?: ((event: Event) => void) | undefined;\n className?: string | undefined;\n asChild?: boolean | undefined;\n children?: ReactNode;\n }>;\n CheckboxItem: React.ComponentType<{\n checked?: boolean | undefined;\n disabled?: boolean | undefined;\n onSelect?: ((event: Event) => void) | undefined;\n onCheckedChange?: ((checked: boolean) => void) | undefined;\n className?: string | undefined;\n children?: ReactNode;\n }>;\n Sub: React.ComponentType<{ children?: ReactNode }>;\n SubTrigger: React.ComponentType<{\n onPointerLeave?: ((event: ReactPointerEvent<HTMLElement>) => void) | undefined;\n disabled?: boolean | undefined;\n className?: string | undefined;\n children?: ReactNode;\n }>;\n SubContent: React.ComponentType<{ className?: string | undefined; children?: ReactNode; onFocusOutside?: (event: CustomEvent<{ originalEvent: FocusEvent }>) => void; onPointerDownOutside?: (event: CustomEvent<{ originalEvent: PointerEvent }>) => void }>;\n Separator: React.ComponentType<{ className?: string }>;\n Label: React.ComponentType<{ className?: string; children?: ReactNode }>;\n Shortcut: React.ComponentType<{ className?: string; children?: ReactNode }>;\n}\n\nconst dropdownFamily = {\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n Sub: DropdownMenuSub,\n SubTrigger: DropdownMenuSubTrigger,\n SubContent: DropdownMenuSubContent,\n Separator: DropdownMenuSeparator,\n Label: DropdownMenuLabel,\n Shortcut: DropdownMenuShortcut,\n} as unknown as MenuFamily;\n\nconst contextFamily = {\n Item: ContextMenuItem,\n CheckboxItem: ContextMenuCheckboxItem,\n Sub: ContextMenuSub,\n SubTrigger: ContextMenuSubTrigger,\n SubContent: ContextMenuSubContent as MenuFamily[\"SubContent\"],\n Separator: ContextMenuSeparator,\n Label: ContextMenuLabel,\n Shortcut: ContextMenuShortcut,\n} as unknown as MenuFamily;\n\nconst DESTRUCTIVE_ITEM_CLASS =\n \"text-destructive-ink focus:bg-destructive/10 focus:text-destructive-ink [&_svg]:text-destructive-ink\";\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\nfunction EntryInner({\n entry,\n Shortcut,\n showShortcut = true,\n}: {\n entry: ItemMenuEntry;\n Shortcut: MenuFamily[\"Shortcut\"];\n showShortcut?: boolean;\n}) {\n const Icon = entry.icon;\n const destructive = isCommand(entry) && entry.tone === \"destructive\";\n const shortcutText =\n isCommand(entry) || isCheckbox(entry)\n ? (entry.shortcut ?? entry.shortcutKey?.toUpperCase())\n : undefined;\n // The only second line an entry draws is why it is disabled; `description`\n // is hover text (Arman, 2026-10-14: no \"novels\" in menus).\n const secondLine = entry.disabled && entry.disabledReason ? entry.disabledReason : undefined;\n\n return (\n <>\n {Icon && (\n <Icon\n className={cn(\n \"h-4 w-4 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\" title={entry.description}>{entry.label}</span>\n {secondLine && (\n <span className=\"truncate type-secondary text-muted-foreground\">\n {secondLine}\n </span>\n )}\n </span>\n {entry.badge && (\n <span className=\"ml-2 shrink-0 rounded border border-border px-1.5 py-px type-meta font-medium uppercase tracking-wide text-muted-foreground\">\n {entry.badge}\n </span>\n )}\n {showShortcut && shortcutText && <Shortcut>{shortcutText}</Shortcut>}\n </>\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 && (\n <family.Label className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {section.label}\n </family.Label>\n )}\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 disabled={entry.disabled} className=\"gap-2\" onPointerLeave={(event) => {\n if (entry.renderContent && event.relatedTarget instanceof Element && event.relatedTarget.closest(\"[data-canonical-alchemy-submenu]\")) event.preventDefault();\n }}>\n <EntryInner\n entry={entry}\n Shortcut={family.Shortcut}\n showShortcut={false}\n />\n </family.SubTrigger>\n <family.SubContent onFocusOutside={keepCanonicalPaletteInteraction} onPointerDownOutside={keepCanonicalPaletteInteraction} className={entry.renderContent ? \"p-0 [--radix-popover-content-available-height:var(--radix-dropdown-menu-content-available-height)]\" : undefined}>\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 checked={entry.checked}\n disabled={entry.disabled}\n onSelect={(e) => e.preventDefault()} // stay open\n onCheckedChange={(next) => runToggle(entry, next)}\n className=\"gap-2\"\n >\n <EntryInner entry={entry} Shortcut={family.Shortcut} />\n </family.CheckboxItem>\n );\n }\n\n if (isLink(entry)) {\n return (\n <family.Item asChild disabled={entry.disabled} className=\"gap-2\">\n <a\n href={entry.href}\n target={entry.target}\n rel={entry.target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n onClick={onCloseRequest}\n >\n <EntryInner entry={entry} Shortcut={family.Shortcut} />\n </a>\n </family.Item>\n );\n }\n\n // command\n return (\n <family.Item\n disabled={entry.disabled}\n onSelect={() => runCommand(entry, toastPromise)}\n className={cn(\n \"gap-2\",\n entry.tone === \"destructive\" && DESTRUCTIVE_ITEM_CLASS,\n )}\n >\n <EntryInner entry={entry} Shortcut={family.Shortcut} />\n </family.Item>\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 contentMinWidth = \"12rem\",\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 ────────────────────────────────────────\n //\n // 🚨 Measured on production `/agents/all` at 1024x768 (one-resolution\n // FIX-Q13): the menu's DANGER section sat at y~735, past the clip. It was\n // reachable — the panel caps at the height Radix measured and scrolls — but\n // the ONLY thing saying so was a `mask-image` fade, which renders the very\n // control it is hinting at as a half-transparent smear. A live destructive\n // action that looks half-erased is the disabled-looking screen law 4\n // forbids, and the walker read the control as dead.\n //\n // So the fade is gone and the overflow is DECLARED: the panel is a flex\n // column that does not scroll, the entries scroll inside it, and an explicit\n // bar — legible text, a chevron, and a click that scrolls — sits at the\n // bottom edge whenever there is more below. `state` is measured, so a menu\n // that fits shows nothing at all.\n const scrollFade = useScrollFade();\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const setViewport = useCallback(\n (node: HTMLDivElement | null) => {\n viewportRef.current = node;\n scrollFade.ref(node);\n },\n [scrollFade.ref],\n );\n const scrollToEnd = () => {\n const el = viewportRef.current;\n if (!el) return;\n el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n };\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 <DropdownMenuContent\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\n // taller than a short viewport. Without this the overflow is simply\n // UNREACHABLE — Radix positions the panel but does not scroll it, so\n // Delete silently falls off the bottom of the screen.\n //\n // Bound to Radix's OWN available-height var, not a vh fraction: a\n // plain `max-h-[70vh]` still overhangs, because 70vh is measured\n // against the viewport while the panel starts partway down it.\n //\n // No arbitrary height cap: a menu is allowed to be long (Chrome's own\n // app menu is ~20 entries). It uses the space it has, and the fade\n // tells the eye when there is more.\n collisionPadding={12}\n className={cn(\n \"flex max-h-[var(--radix-dropdown-menu-content-available-height)] flex-col overflow-hidden p-0\",\n )}\n style={{ minWidth: contentMinWidth }}\n {...(onCloseAutoFocus ? { onCloseAutoFocus } : {})}\n onKeyDown={makeShortcutHandler(resolved, () =>\n handleOpenChange(false),\n toastPromise)}\n >\n <div\n ref={setViewport}\n data-slot=\"item-menu-viewport\"\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-1\"\n >\n {resolved.header?.title && (\n <DropdownMenuLabel className=\"text-xs\">\n {resolved.header.title}\n {resolved.header.description && (\n <span className=\"mt-0.5 block type-meta font-normal text-muted-foreground\">\n {resolved.header.description}\n </span>\n )}\n </DropdownMenuLabel>\n )}\n <MenuSections\n family={dropdownFamily}\n sections={resolved.sections}\n onCloseRequest={() => handleOpenChange(false)}\n />\n </div>\n {scrollFade.state.bottom && (\n <button\n type=\"button\"\n data-slot=\"item-menu-more-below\"\n // Not a menu item: it must never take roving focus or be picked\n // by type-ahead, and Escape/arrow keys still belong to the list.\n tabIndex={-1}\n aria-hidden=\"true\"\n // Radix would otherwise close the menu on the pointer-down that\n // starts this click.\n onPointerDown={(e) => e.preventDefault()}\n onClick={scrollToEnd}\n className=\"flex w-full shrink-0 items-center justify-center gap-1 border-t border-border bg-popover px-2 py-1 text-[11px] font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <ChevronDown className=\"h-3 w-3\" />\n More actions below\n </button>\n )}\n </DropdownMenuContent>\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 <ContextMenuContent\n className=\"z-[9999] min-w-[12rem]\"\n onCloseAutoFocus={onCloseAutoFocus}\n >\n {resolved.header?.title && (\n <ContextMenuLabel className=\"text-xs font-medium text-muted-foreground\">\n {resolved.header.title}\n </ContextMenuLabel>\n )}\n <MenuSections family={contextFamily} sections={resolved.sections} onCloseRequest={() => onOpenChange?.(false)} />\n </ContextMenuContent>\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 * 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 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 && (\n <span className=\"item-shift flex shrink-0 items-center gap-1 pr-0.5\">\n {trailing}\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 className={cn(\"shrink-0\", !sideBySide && \"absolute right-1 top-1/2 -translate-y-1/2\")}\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tap-target/tap-target-guard.ts","../src/layout-scale.ts","../src/tap-target/tap-surface.tsx","../src/tap-target/tap-features.tsx","../src/tap-target/tap-target-button.tsx"],"sourcesContent":["\"use client\";\n\n// THE TAP-TARGET GUARD — development builds only.\n//\n// The lock layer in tap-target.css makes a tap button's own box, pill and\n// glyph impossible to resize from outside. What CSS cannot stop is a caller\n// bending the system AROUND the button: a parent that adds `gap` between two\n// tap buttons, a wrapper with margin or padding, a local override of a\n// `--matrx-tap-*` token, a utility class smuggled in through `className`.\n// After a tap button mounts, this guard measures it in the real layout and,\n// on any of those, marks it `data-matrx-tap-violation`: the stylesheet then\n// paints it as a giant red box carrying the reason, and the console names\n// the element.\n//\n// OFF until the host turns it on with `enableTapTargetGuard()` — from code the\n// HOST compiles, e.g. matrx-frontend's dev-only client boot. Never gate it on\n// `process.env.NODE_ENV` in here: this package's own build inlines that\n// expression, so a \"dev only\" check written here would run in production too\n// (see @ai-matrx/associations' context.tsx for the outage that taught this).\n\nimport { useCallback, useRef, type MutableRefObject, type Ref } from \"react\";\nimport { layoutScale } from \"../layout-scale\";\n\n// A `Symbol.for` slot on globalThis, like the link seam: the `.` and\n// `./buttons` bundles each inline this module, and one switch must reach both.\nconst GUARD_SLOT = Symbol.for(\"@ai-matrx/tap-target:guard\");\ntype GlobalWithGuard = typeof globalThis & { [GUARD_SLOT]?: boolean };\n\n/** Turn the development guard on (or off). Call once at client boot, only in\n * development builds of the host. */\nexport function enableTapTargetGuard(on = true): void {\n (globalThis as GlobalWithGuard)[GUARD_SLOT] = on;\n if (on) startPillInsetScan();\n}\n\nfunction guardOn(): boolean {\n return (globalThis as GlobalWithGuard)[GUARD_SLOT] === true;\n}\n\nconst TOKENS = [\n \"--matrx-tap-box\",\n \"--matrx-tap-gap\",\n \"--matrx-tap-pill-size\",\n \"--matrx-tap-pill-sm-size\",\n \"--matrx-tap-wide-size\",\n \"--matrx-tap-icon-size\",\n \"--matrx-tap-touch-min\",\n \"--matrx-tap-target-size\",\n] as const;\n\n/** The only scopes that may move tap tokens, and which ones — each owned by\n * this package's own CSS: the table density scales (tap-target.css) and\n * Alchemy's 18px trigger glyph (content-transfer.css). */\nconst SANCTIONED: ReadonlyArray<{ scope: string; tokens: ReadonlySet<string> }> = [\n {\n scope: \"[data-matrx-table][data-matrx-table-density]\",\n tokens: new Set([\n \"--matrx-tap-target-size\",\n \"--matrx-tap-pill-size\",\n \"--matrx-tap-wide-size\",\n \"--matrx-tap-pill-sm-size\",\n \"--matrx-tap-icon-size\",\n ]),\n },\n { scope: \"[data-alchemy-trigger]\", tokens: new Set([\"--matrx-tap-icon-size\"]) },\n // THE ONE CONTROL scope (controls.css): tap buttons beside the 28px controls\n // take the controls' height — a 28px pill in a 34px box, the same 6px apart.\n {\n scope: \"[data-matrx-controls]\",\n tokens: new Set([\n \"--matrx-tap-target-size\",\n \"--matrx-tap-pill-size\",\n \"--matrx-tap-wide-size\",\n \"--matrx-tap-pill-sm-size\",\n ]),\n },\n];\nconst TABLE_SCOPE = SANCTIONED[0]!.scope;\nconst CONTROL_SCOPE = SANCTIONED[2]!.scope;\nconst TAP_ITEM = \".matrx-tap-target, .matrx-tap-group\";\n\n/** `className` on a tap button is the GLYPH COLOR. Anything that sizes,\n * spaces, positions or fills is misuse. */\nconst NON_COLOR_CLASS =\n /^(?:[^\\s:]+:)*!?-?(?:\\[&|scale|translate|h|w|size|min-h|min-w|max-h|max-w|p|px|py|ps|pe|pt|pb|pl|pr|m|mx|my|ms|me|mt|mb|ml|mr|gap|space-x|space-y|bg|rounded|border|ring|shadow|absolute|relative|fixed|sticky|inset|top|left|right|bottom|flex|grid|block|inline|hidden|z|shrink|grow|basis|self|order)(?:-|$|\\[)/;\n\nexport function classNameMisuse(className: string | undefined): string | null {\n if (!guardOn() || !className) return null;\n const bad = className.split(/\\s+/).filter((t) => t && NON_COLOR_CLASS.test(t));\n return bad.length\n ? `className is the glyph color only — remove \"${bad.join(\" \")}\"`\n : null;\n}\n\n/**\n * The horizontal space a wrapper adds around what it holds. An `auto` margin (`ml-auto` pushing a\n * toolbar's actions to the end) only aligns — the browser resolves it to pixels in\n * `getComputedStyle`, so read the computed keyword from the typed OM and count it as zero.\n */\nexport function wrapperSpace(el: Element, view: Window): number {\n const pcs = view.getComputedStyle(el);\n const typed = (el as Element & { computedStyleMap?: () => { get(p: string): unknown } }).computedStyleMap?.();\n const margin = (prop: \"margin-left\" | \"margin-right\", resolved: string) =>\n typed && String(typed.get(prop)) === \"auto\" ? 0 : px(resolved);\n return margin(\"margin-left\", pcs.marginLeft) + margin(\"margin-right\", pcs.marginRight) + px(pcs.paddingLeft) + px(pcs.paddingRight);\n}\n\nfunction px(value: string): number {\n const n = Number.parseFloat(value);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction describe(el: Element): string {\n const cls = typeof el.className === \"string\" ? el.className.trim().split(/\\s+/).slice(0, 4).join(\".\") : \"\";\n return `<${el.tagName.toLowerCase()}${cls ? `.${cls}` : \"\"}>`;\n}\n\n/** Elements that ride along with a tap button without taking space from it\n * (a badge, a capsule, a tooltip portal anchor). */\nfunction isDecor(el: Element, view: Window): boolean {\n const cs = view.getComputedStyle(el);\n return cs.position === \"absolute\" || cs.position === \"fixed\" || cs.display === \"none\";\n}\n\nfunction tapCount(el: Element): number {\n return el.matches(TAP_ITEM) ? 1 : el.querySelectorAll(TAP_ITEM).length;\n}\n\n/** Visible text in `container` outside `tap` and outside decor (a badge's\n * count is decor) — a wrapper with its own words is a chip, not a wrapper. */\nfunction ownText(container: Element, tap: Element, view: Window): string {\n let out = \"\";\n const walk = (node: Node) => {\n if (node === tap) return;\n if (node.nodeType === 3) out += node.textContent ?? \"\";\n else if (node.nodeType === 1 && !isDecor(node as Element, view)) node.childNodes.forEach(walk);\n };\n container.childNodes.forEach(walk);\n return out.trim();\n}\n\n/** True when `child` is a tap button, or a plain wrapper whose only content\n * is ONE tap button (plus decor) — never a search box that happens to hold\n * a clear button, never a chip with words. */\nfunction isTapSlot(child: Element, view: Window): boolean {\n if (child.matches(TAP_ITEM)) return true;\n if (tapCount(child) !== 1) return false;\n const tap = child.querySelector(TAP_ITEM)!;\n const controls = Array.from(child.querySelectorAll(\"input, select, textarea, button, a, [role='button']\"));\n if (controls.some((c) => c !== tap && !tap.contains(c))) return false;\n return ownText(child, tap, view) === \"\";\n}\n\nlet probe: { key: string; target: number; pill: number; sm: number; smPill: number; wide: number; icon: number } | null = null;\n\n/** What the package's own CSS produces with no surrounding context — the\n * canon every mounted button is measured against. Re-measured whenever the\n * root tokens change (the lab page switches the gap). */\nfunction canon(doc: Document) {\n const view = doc.defaultView!;\n const root = view.getComputedStyle(doc.documentElement);\n const key = TOKENS.map((t) => root.getPropertyValue(t)).join(\"|\");\n if (probe?.key === key) return probe;\n const host = doc.createElement(\"div\");\n host.setAttribute(\"aria-hidden\", \"true\");\n host.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none;left:-9999px;top:0\";\n host.innerHTML =\n '<button class=\"matrx-tap-target\"><div class=\"matrx-tap-pill\"><svg class=\"matrx-tap-icon\"></svg></div></button>' +\n '<button class=\"matrx-tap-target matrx-tap-target-sm\"><div class=\"matrx-tap-pill matrx-tap-pill-sm\"></div></button>' +\n '<button class=\"matrx-tap-target matrx-tap-target-inline\"><div class=\"matrx-tap-pill matrx-tap-pill-inline\"></div></button>';\n doc.body.appendChild(host);\n const [a, b, w] = Array.from(host.children) as HTMLElement[];\n probe = {\n key,\n target: a!.offsetHeight,\n pill: (a!.firstElementChild as HTMLElement).offsetHeight,\n icon: px(view.getComputedStyle(a!.querySelector(\"svg\")!).height),\n sm: b!.offsetHeight,\n smPill: (b!.firstElementChild as HTMLElement).offsetHeight,\n wide: (w!.firstElementChild as HTMLElement).offsetHeight,\n };\n host.remove();\n return probe;\n}\n\n/** Returns the first rule this mounted tap button breaks, or null. */\nexport function findTapViolation(el: HTMLElement): string | null {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n if (!view || !el.isConnected) return null;\n const cs = view.getComputedStyle(el);\n if (cs.display === \"none\") return null;\n\n // 1. Tokens are the package's alone. Only the table-density scope may move\n // the three it owns.\n const root = view.getComputedStyle(doc.documentElement);\n // Both scaled scopes size by their own tokens; the canon check below reads\n // the root canon, so it applies outside them only.\n const inTable = el.closest(TABLE_SCOPE) !== null || el.closest(CONTROL_SCOPE) !== null;\n const moved = new Set<string>();\n for (const token of TOKENS) {\n const mine = cs.getPropertyValue(token).trim();\n const base = root.getPropertyValue(token).trim();\n if (mine === base) continue;\n if (!SANCTIONED.some((s) => s.tokens.has(token) && el.closest(s.scope))) {\n return `${token} overridden to \"${mine}\" — tap geometry is not configurable`;\n }\n moved.add(token);\n }\n\n // 2. Measured geometry equals the canon (outside table density, which\n // sizes by its own tokens).\n const sm = el.classList.contains(\"matrx-tap-target-sm\");\n const inline = /matrx-tap-target-(?:inline|mobile-icon-only)/.test(el.className);\n const pill = el.querySelector<HTMLElement>(\":scope > .matrx-tap-pill\");\n const icon = pill?.querySelector(\".matrx-tap-icon\") ?? null;\n // A host touch floor (min-width / min-height) may enlarge a box; that is\n // the floor working, not a bend.\n const floored =\n px(cs.minHeight) >= el.offsetHeight - 0.5 || px(cs.minWidth) >= el.offsetWidth - 0.5;\n if (!inTable && pill && !floored) {\n const c = canon(doc);\n const box = sm ? c.sm : c.target;\n // A labeled pill is a WIDE shape (shorter than a round one); below the\n // `sm` breakpoint a mobile-icon-only pill is round again — either is canon.\n const pillSizes = sm ? [c.smPill] : inline ? [c.pill, c.wide] : [c.pill];\n if (Math.abs(el.offsetHeight - box) > 0.5) return `button is ${el.offsetHeight}px tall, canon is ${box}px`;\n if (!inline && Math.abs(el.offsetWidth - box) > 0.5) return `button is ${el.offsetWidth}px wide, canon is ${box}px`;\n if (!pillSizes.some((p) => Math.abs(pill.offsetHeight - p) <= 0.5)) {\n return `pill is ${pill.offsetHeight}px, canon is ${pillSizes.join(\" or \")}px`;\n }\n if (icon && !moved.has(\"--matrx-tap-icon-size\")) {\n const size = px(view.getComputedStyle(icon).height);\n if (Math.abs(size - c.icon) > 0.5) return `glyph is ${size}px, canon is ${c.icon}px`;\n }\n }\n\n // 3. Nothing adds space around it. Climb the wrappers that hold only this\n // button (plus decor such as a badge); none may carry inline margin or\n // padding. A tap button inside a group is represented by its group.\n let slot: Element = el;\n if (el.parentElement?.matches(\".matrx-tap-group-row, .matrx-tap-search-measure\")) {\n const group = el.closest(\".matrx-tap-group\");\n if (group && tapCount(el.parentElement) > 1) return null;\n slot = group ?? el;\n }\n for (let depth = 0; depth < 2; depth += 1) {\n const parent: HTMLElement | null = slot.parentElement;\n if (!parent || parent === doc.body) break;\n const others = Array.from(parent.children).filter((c) => c !== slot && !isDecor(c, view));\n if (others.length > 0) break; // `parent` is the row\n if (ownText(parent, slot, view) !== \"\") break; // a chip or a titled header\n const space = wrapperSpace(parent, view);\n if (space > 0.5) {\n return `${describe(parent)} adds ${space}px around a tap button — tap buttons space themselves`;\n }\n slot = parent;\n }\n\n // 4. The row adds no gap between tap buttons.\n const row = slot.parentElement;\n if (row) {\n const rcs = view.getComputedStyle(row);\n const flexOrGrid = /flex|grid/.test(rcs.display);\n const neighbours = Array.from(row.children).filter((c) => c !== slot && isTapSlot(c, view));\n if (flexOrGrid && neighbours.length > 0) {\n const horizontal = rcs.display.includes(\"grid\") || !rcs.flexDirection.startsWith(\"column\");\n const gap = px(horizontal ? rcs.columnGap : rcs.rowGap);\n if (gap > 0.5) {\n return `${describe(row)} adds a ${gap}px gap between tap buttons — remove it; tap buttons space themselves`;\n }\n }\n }\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* PLACEMENT — the three rules a tap button's SURROUNDINGS must keep */\n/* (owner, 2026-10-02). Reported as a WARNING (a dashed outline and one */\n/* console error naming the fix), not the misuse box: they are about */\n/* the page around the button, and the whole app is being brought into */\n/* line with them. */\n/* 1. GLASS ONLY FLOATS — glass is see-through; it belongs on a bar */\n/* that floats over moving content (position fixed/sticky) or on a */\n/* plane marked `data-matrx-glass-plane`. On a page, card, toast or */\n/* table use `variant=\"transparent\"` / a solid group. */\n/* 2. ALL GLASS OR NONE — a glass item's row holds only glass items */\n/* (glass tap buttons, glass groups, or `data-matrx-glass` pieces). */\n/* 3. NEIGHBOURS KEEP THEIR HALF-GAP — a tap box carries 3px of unseen */\n/* space each side (box − pill = one gap, 6px). Anything beside it */\n/* adds its own 3px, so the visible distance is always one gap. */\n/* ------------------------------------------------------------------ */\n\nconst GLASS = \".matrx-glass-thin-border, .matrx-glass-interactive\";\n\nfunction isGlassItem(node: Element): boolean {\n if (node.hasAttribute(\"data-matrx-glass\")) return true;\n if (node.matches(\".matrx-tap-group\")) return node.querySelector(\":scope > .matrx-tap-group-capsule.matrx-glass-thin-border\") !== null;\n if (node.matches(\".matrx-tap-target\")) return node.querySelector(`:scope > .matrx-tap-pill:is(${GLASS})`) !== null;\n // A plain wrapper whose only content is ONE tap button (plus decor such as a\n // badge) is that button: a badge host around a glass button is glass.\n const view = node.ownerDocument.defaultView;\n if (view && isTapSlot(node, view)) return isGlassItem(node.querySelector(TAP_ITEM)!);\n return false;\n}\n\nconst SCROLLS = /^(auto|scroll|overlay)$/;\n\n/** True when `el` rides a bar over moving content: a fixed/sticky ancestor (or\n * a glass plane) reached BEFORE any scroll container. Inside a scroller the\n * button IS the moving content — an app root that is itself `position:\n * fixed` (the shell) must not make every page button \"float\". */\nfunction floats(el: Element, view: Window): boolean {\n for (let n: Element | null = el; n && n !== el.ownerDocument.body; n = n.parentElement) {\n if (n.hasAttribute(\"data-matrx-glass-plane\")) return true;\n const cs = view.getComputedStyle(n);\n if (cs.position === \"fixed\" || cs.position === \"sticky\") return true;\n if (n !== el && (SCROLLS.test(cs.overflowY) || SCROLLS.test(cs.overflowX))) return false;\n }\n return false;\n}\n\n/** True when the edge of `wrapper` that faces a neighbour (`side` is where the\n * wrapper sits relative to that neighbour) is itself a tap slot: that button\n * carries its own 3px half-gap, so the wrapper is spacing-correct however many\n * tap buttons it holds (the fading mic + More cluster beside Send). A wrapper\n * whose edge is text or a field is not — it still has to keep its distance. */\nfunction facesWithTapSlot(wrapper: Element, side: \"after\" | \"before\", view: Window): boolean {\n for (let node: Element | null = wrapper; node; ) {\n if (isTapSlot(node, view)) return true;\n const kids: Element[] = Array.from(node.children).filter((c) => !isDecor(c, view));\n node = (side === \"after\" ? kids[0] : kids[kids.length - 1]) ?? null;\n }\n return false;\n}\n\nfunction visible(el: Element, view: Window): boolean {\n if (el.getAttribute(\"aria-hidden\") === \"true\" || isDecor(el, view)) return false;\n const r = el.getBoundingClientRect();\n return r.width > 1 && r.height > 1;\n}\n\nconst INTERACTIVE = \"button, a[href], input, select, textarea, [role='button'], svg, img\";\n\n/** The box the eye sees on the side of `sib` that faces the tap button. An\n * unpainted layout wrapper (no fill, no border on that side, no words of its\n * own) is invisible, so the distance is judged at the first thing inside it —\n * the wrapper around ProTextarea's mic sits 3px from Expand while the mic\n * capsule, which keeps its own 3px margin, sits one gap away (2026-10-13). */\nfunction facingBox(sib: Element, side: \"after\" | \"before\", view: Window): Element {\n let node = sib;\n for (;;) {\n if (node.matches(INTERACTIVE)) return node;\n const cs = view.getComputedStyle(node);\n const fill = cs.backgroundColor;\n if ((fill && fill !== \"rgba(0, 0, 0, 0)\" && fill !== \"transparent\") || px(side === \"after\" ? cs.borderLeftWidth : cs.borderRightWidth) > 0) {\n return node;\n }\n if (Array.from(node.childNodes).some((c) => c.nodeType === 3 && c.textContent?.trim())) return node;\n const kids = Array.from(node.children).filter((c) => visible(c, view));\n const next = side === \"after\" ? kids[0] : kids[kids.length - 1];\n if (!next) return node;\n node = next;\n }\n}\n\n/** The first placement rule this tap button's surroundings break, or null. */\nexport function findTapPlacementWarning(el: HTMLElement): string | null {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n if (!view || !el.isConnected) return null;\n // A button inside a group is judged as its group.\n const slot: Element = el.closest(\".matrx-tap-group\") ?? el;\n const glass = isGlassItem(slot);\n\n if (glass && !floats(slot, view)) {\n return 'glass on a solid surface — glass only floats over moving content; use variant=\"transparent\" (or a solid group)';\n }\n\n const row = slot.parentElement;\n if (!row) return null;\n if (glass) {\n const mixed = Array.from(row.children).find((c) => c !== slot && visible(c, view) && !isGlassItem(c));\n if (mixed) return `glass beside non-glass ${describe(mixed)} — make the row all glass or none`;\n }\n\n const pill = (el.querySelector(\":scope > .matrx-tap-pill\") as HTMLElement | null) ?? (slot.querySelector(\".matrx-tap-group-capsule\") as HTMLElement | null);\n if (!pill) return null;\n const gap = px(view.getComputedStyle(el).getPropertyValue(\"--matrx-tap-gap\")) || 6;\n const p = pill.getBoundingClientRect();\n if (p.width === 0) return null;\n // Distances are judged in LAYOUT pixels: inside a zoomed (transformed) tile a screen distance\n // is the layout distance times the scale.\n const scale = layoutScale(pill);\n for (const [side, sib] of [[\"after\", slot.nextElementSibling], [\"before\", slot.previousElementSibling]] as const) {\n if (!sib || !visible(sib, view) || isTapSlot(sib, view) || isGlassItem(sib) || facesWithTapSlot(sib, side, view)) continue;\n if (Math.abs(sib.getBoundingClientRect().top + sib.getBoundingClientRect().height / 2 - (p.top + p.height / 2)) > p.height) continue; // not on this row\n const box = facingBox(sib, side, view);\n const r = box.getBoundingClientRect();\n const cs = view.getComputedStyle(box);\n const distance =\n (side === \"after\" ? r.left - p.right : p.left - r.right) / scale + (side === \"after\" ? px(cs.paddingLeft) : px(cs.paddingRight));\n if (distance < gap - 0.5) {\n return `${describe(sib)} sits ${Math.round(distance)}px from the pill — anything beside a tap button adds its own ${gap / 2}px (the box only carries ${gap / 2}px)`;\n }\n }\n return null;\n}\n\nconst reported = new Set<string>();\n\nfunction report(el: HTMLElement, reason: string) {\n el.setAttribute(\"data-matrx-tap-violation\", reason);\n const key = `${reason}@${el.getAttribute(\"aria-label\") ?? el.textContent ?? \"\"}`;\n if (reported.has(key)) return;\n reported.add(key);\n console.error(`[tap-target] ${reason}`, el);\n}\n\nconst mounted = new Set<HTMLElement>();\nlet resizeTimer: ReturnType<typeof setTimeout> | null = null;\nlet listening = false;\n\nfunction check(node: HTMLElement) {\n const reason = findTapViolation(node);\n if (reason) {\n report(node, reason);\n return;\n }\n node.removeAttribute(\"data-matrx-tap-violation\");\n const warning = findTapPlacementWarning(node);\n if (warning) {\n node.setAttribute(\"data-matrx-tap-warning\", warning);\n const key = `w:${warning}@${node.getAttribute(\"aria-label\") ?? \"\"}`;\n if (!reported.has(key)) {\n reported.add(key);\n console.error(`[tap-target] ${warning}`, node);\n }\n } else node.removeAttribute(\"data-matrx-tap-warning\");\n}\n\nfunction listenForResize(view: Window) {\n if (listening) return;\n listening = true;\n view.addEventListener(\"resize\", () => {\n if (resizeTimer) clearTimeout(resizeTimer);\n resizeTimer = setTimeout(() => mounted.forEach((n) => (n.isConnected ? check(n) : mounted.delete(n))), 200);\n });\n // A button is judged once, at mount — but its neighbours keep changing (a\n // loading placeholder becomes the real control). Re-judge a button when the\n // row it sits in gains or loses children, so a mark never outlives the\n // neighbour it named (2026-10-13: \"New run\" kept a red outline for a\n // skeleton that had already left the header).\n const Observer = (view as Window & { MutationObserver?: typeof MutationObserver }).MutationObserver;\n if (!Observer || !view.document.body) return;\n const changedRows = new Set<Node>();\n let rowTimer: ReturnType<typeof setTimeout> | null = null;\n new Observer((records) => {\n for (const r of records) changedRows.add(r.target);\n if (rowTimer) clearTimeout(rowTimer);\n rowTimer = setTimeout(() => {\n mounted.forEach((n) => {\n if (!n.isConnected) return void mounted.delete(n);\n const row = (n.closest(\".matrx-tap-group\") ?? n).parentElement;\n if (row && changedRows.has(row)) check(n);\n });\n changedRows.clear();\n }, 200);\n }).observe(view.document.body, { childList: true, subtree: true });\n}\n\nfunction assignRef<T>(ref: Ref<T> | undefined, value: T | null) {\n if (typeof ref === \"function\") ref(value);\n else if (ref) (ref as MutableRefObject<T | null>).current = value;\n}\n\n/**\n * The callback ref every tap trigger carries. In production it only forwards\n * the caller's ref; in development it also measures the trigger once it is in\n * the layout and paints a violation.\n */\nexport function useTapGuardRef<T extends HTMLElement>(\n forwarded: Ref<T> | undefined,\n propViolation: string | null,\n): (node: T | null) => void {\n const current = useRef<T | null>(null);\n return useCallback(\n (node: T | null) => {\n assignRef(forwarded, node);\n if (current.current && current.current !== node) mounted.delete(current.current);\n current.current = node;\n if (!guardOn() || !node) return;\n if (propViolation) {\n report(node, propViolation);\n return;\n }\n const view = node.ownerDocument.defaultView;\n if (!view) return;\n mounted.add(node);\n listenForResize(view);\n view.requestAnimationFrame(() => check(node));\n },\n [forwarded, propViolation],\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* THE PILL-INSET GUARD (0.60.10). A pill is balanced when its INK sits */\n/* the same distance from both edges. On 2026-10-04 every icon+label */\n/* pill read off-centre (1.3–3.3px) because padding was shaved on the */\n/* glyph side by a guess at the glyph's air. The trim in tap-target.css */\n/* now removes each glyph's real air; this measures the result in the */\n/* real layout and marks any pill whose ink insets differ by more than */\n/* 2px — dashed red outline + one console error naming both numbers. */\n/* ------------------------------------------------------------------ */\n\nconst PILL_TOLERANCE_PX = 2;\nconst PILL_ITEMS = \"button, a[href], [role='button'], [role='tab'], [role='radio'], [role='menuitem']\";\nconst PILL_CANDIDATES = \"button, a[href], [role='button'], .rounded-full, .matrx-tap-pill-inline, .matrx-tap-pill-mobile-icon-only\";\n\n/** Horizontal ink extents inside `el`: glyph geometry for svgs, text runs for text. */\nfunction inkExtents(el: Element): { left: number; right: number } | null {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n if (!view) return null;\n let left = Infinity;\n let right = -Infinity;\n const walker = doc.createTreeWalker(el, 0x1 | 0x4 /* SHOW_ELEMENT | SHOW_TEXT */);\n let n: Node | null;\n while ((n = walker.nextNode())) {\n if (n.nodeType === 1) {\n const node = n as Element;\n const cs = view.getComputedStyle(node);\n if (cs.display === \"none\" || cs.visibility === \"hidden\" || cs.position === \"absolute\") continue;\n const tag = node.tagName.toLowerCase();\n if (tag === \"img\" || tag === \"picture\" || tag === \"video\" || tag === \"canvas\") {\n // A picture (a favicon, an avatar) is ink by its box — it draws its own pixels, and a logo\n // renders exactly as it is, never tinted to make a guard see it (2026-10-13: every\n // favicon-led link pill read \"29px left vs 10px right\" because the image was invisible here).\n const r = node.getBoundingClientRect();\n if (r.width > 0) {\n left = Math.min(left, r.left);\n right = Math.max(right, r.right);\n }\n continue;\n }\n if (tag !== \"svg\" && (node.getAttribute(\"role\") === \"status\" || node.getAttribute(\"role\") === \"progressbar\")) {\n // A busy spinner drawn with borders (its rings are absolute, so nothing below sees them)\n // is ink by its box: a pill whose icon turned into a spinner read \"44px left vs 20px right\".\n const r = node.getBoundingClientRect();\n if (r.width > 0) {\n left = Math.min(left, r.left);\n right = Math.max(right, r.right);\n }\n continue;\n }\n if (tag !== \"svg\") {\n // A painted chip inside the pill (a count badge) is ink by its box: its fill is what the eye sees.\n const paintedChip = (cs.backgroundColor !== \"rgba(0, 0, 0, 0)\" && cs.backgroundColor !== \"transparent\") || parseFloat(cs.borderLeftWidth) > 0;\n if (paintedChip) {\n const r = node.getBoundingClientRect();\n if (r.width > 0) {\n left = Math.min(left, r.left);\n right = Math.max(right, r.right);\n }\n }\n continue;\n }\n const svg = node as SVGGraphicsElement;\n if (typeof svg.getBBox !== \"function\" || typeof svg.getScreenCTM !== \"function\") continue;\n const bb = svg.getBBox();\n const ctm = svg.getScreenCTM();\n if (!ctm || bb.width === 0) continue;\n if (Math.abs(ctm.b) > 0.001 || Math.abs(ctm.c) > 0.001) {\n // A turning glyph (a busy spinner) has no fixed ink: judge it by its layout box, centered\n // where the rotation centers it — never by a mid-turn snapshot of its paths.\n const r = node.getBoundingClientRect();\n const half = (parseFloat(cs.width) || r.width) / 2;\n const mid = r.left + r.width / 2;\n left = Math.min(left, mid - half);\n right = Math.max(right, mid + half);\n continue;\n }\n const half = ((parseFloat(cs.strokeWidth) || 0) * Math.abs(ctm.a)) / 2;\n const x1 = ctm.a * bb.x + ctm.e;\n const x2 = ctm.a * (bb.x + bb.width) + ctm.e;\n left = Math.min(left, Math.min(x1, x2) - half);\n right = Math.max(right, Math.max(x1, x2) + half);\n } else if (n.nodeValue && n.nodeValue.trim()) {\n const parent = n.parentElement;\n if (!parent || parent.closest(\"svg\")) continue;\n const pcs = view.getComputedStyle(parent);\n if (pcs.visibility === \"hidden\" || pcs.position === \"absolute\") continue;\n const range = doc.createRange();\n range.selectNodeContents(n);\n // A truncated label (`truncate max-w-*`) draws only what its clipping box shows: its text\n // run keeps going past the ellipsis, so the run is clipped to every overflow-hiding box\n // between it and the pill (2026-10-18: a scope chip \"matrx-frontend (LCP test)\" read\n // \"9.0px left vs 5.7px right\" while its ellipsis sat exactly 9px from the edge).\n const clip = textClip(parent, el, view);\n for (const r of Array.from(range.getClientRects())) {\n if (r.width <= 0) continue;\n const rl = Math.max(r.left, clip.left);\n const rr = Math.min(r.right, clip.right);\n if (rr <= rl) continue;\n left = Math.min(left, rl);\n right = Math.max(right, rr);\n }\n }\n }\n return Number.isFinite(left) && Number.isFinite(right) ? { left, right } : null;\n}\n\n/** The horizontal window a text run can paint in: its overflow-clipping ancestors up to (excluding) `pill`. */\nfunction textClip(from: Element, pill: Element, view: Window): { left: number; right: number } {\n let left = -Infinity;\n let right = Infinity;\n for (let node: Element | null = from; node && node !== pill; node = node.parentElement) {\n const cs = view.getComputedStyle(node);\n // overflow-x, or the shorthand's first (x) value where a runtime does not expand it (jsdom)\n const clipsX = (cs.overflowX && cs.overflowX !== \"visible\") || (cs.overflow && !cs.overflow.startsWith(\"visible\"));\n if (clipsX) {\n const r = node.getBoundingClientRect();\n if (r.width > 0) {\n left = Math.max(left, r.left);\n right = Math.min(right, r.right);\n }\n }\n }\n return { left, right };\n}\n\nconst FIELDS = \"input, textarea, select, [contenteditable='true'], [role='textbox'], [role='searchbox'], [role='combobox']\";\n\n/**\n * Only a BUTTON can be a pill whose ink must balance: an interactive element,\n * or the painted pill inside one (a tap button's `.matrx-tap-pill-inline`).\n * A field — or a capsule that holds one, like a rounded search box — aligns its\n * text to an edge by design, and a non-interactive container (a status chip, a\n * wrapper painted `rounded-full`) is never a pill button (2026-10-09: the\n * messenger's search field and messaging's AI chips wore the red outline).\n */\nexport function isPillButton(el: Element): boolean {\n if (el.matches(FIELDS) || el.querySelector(FIELDS) !== null) return false;\n if (el.matches(PILL_ITEMS)) return true;\n if (el.parentElement?.closest(PILL_ITEMS)) return true;\n return el.querySelector(PILL_ITEMS) !== null;\n}\n\n/** Why this pill's ink is off-centre, or null. Only judges a pill — a capsule\n * (radius ≥ half its height) with its own fill or border, carrying ink. */\nexport function findPillInsetWarning(el: HTMLElement): string | null {\n const view = el.ownerDocument.defaultView;\n if (!view || !el.isConnected) return null;\n if (!isPillButton(el)) return null;\n const box = el.getBoundingClientRect();\n const scale = layoutScale(el);\n if (box.width / scale < 20 || box.height / scale < 16 || box.height / scale > 48) return null;\n const cs = view.getComputedStyle(el);\n if (parseFloat(cs.borderTopLeftRadius) < box.height / scale / 2 - 1) return null;\n const painted = cs.backgroundColor !== \"rgba(0, 0, 0, 0)\" && cs.backgroundColor !== \"transparent\";\n if (!painted && !(parseFloat(cs.borderLeftWidth) > 0)) return null;\n // A wide capsule (a stretched select or field) aligns content to an edge on purpose.\n if (box.width / scale > 320) return null;\n // Ink balance is a question only for CENTERED content. A select trigger (value left, chevron\n // right), a field, or a full-width action row that says justify-start aligns its content on\n // purpose — content alignment is placement, not an inset to balance.\n if (cs.display.includes(\"flex\") && ![\"center\", \"normal\"].includes(cs.justifyContent)) return null;\n if (el.matches(\"[data-matrx-control='select'], [data-matrx-control='field']\")) return null;\n // A switch, checkbox or slider carries STATE, not a label: its thumb sits at one end by design\n // (measured 2026-10-04: every connector switch read \"18px left vs 2px right\" in the chat composer).\n if (el.matches(\"[role='switch'], [role='checkbox'], [role='slider'], [role='radio']\")) return null;\n // A TRACK of several controls (a segmented nav, a tab strip) is a container, not a pill: its\n // items sit where the selection puts them, so the ink is lopsided by design — each item is\n // judged on its own (measured 2026-10-05: the shell route nav's icon track read 2px vs 12.5px\n // at 768 because the selected item's fill hugs one end and the last glyph carries its air).\n if (el.querySelectorAll(PILL_ITEMS).length > 1) return null;\n const ink = inkExtents(el);\n if (!ink) return null;\n const left = (ink.left - box.left) / scale;\n const right = (box.right - ink.right) / scale;\n if (left < 0 || right < 0) return null; // clipped / overflowing content: not this guard's question\n if (Math.abs(left - right) <= PILL_TOLERANCE_PX) return null;\n return `pill ink is off-centre: ${left.toFixed(1)}px left vs ${right.toFixed(1)}px right — pad both sides alike and let the glyph trim (tap-target.css, THE OPTICAL GLYPH TRIM) remove the glyph's air; never shave one side by hand`;\n}\n\nlet pillTimer: ReturnType<typeof setTimeout> | null = null;\nlet pillObserver: MutationObserver | null = null;\n\nfunction scanPills(doc: Document) {\n if (!guardOn()) return;\n for (const node of Array.from(doc.querySelectorAll<HTMLElement>(PILL_CANDIDATES))) {\n // A tap button's own pill is judged, not its invisible box.\n if (node.classList.contains(\"matrx-tap-target\")) continue;\n const warning = findPillInsetWarning(node);\n if (warning) {\n if (node.getAttribute(\"data-matrx-pill-inset-warning\") === warning) continue;\n node.setAttribute(\"data-matrx-pill-inset-warning\", warning);\n const key = `p:${warning}@${(node.textContent ?? \"\").trim().slice(0, 40)}`;\n if (!reported.has(key)) {\n reported.add(key);\n console.error(`[tap-target] ${warning}`, node);\n }\n } else if (node.hasAttribute(\"data-matrx-pill-inset-warning\")) {\n node.removeAttribute(\"data-matrx-pill-inset-warning\");\n }\n }\n}\n\nfunction startPillInsetScan() {\n if (pillObserver || typeof document === \"undefined\" || typeof MutationObserver === \"undefined\") return;\n const doc = document;\n const schedule = () => {\n if (pillTimer) clearTimeout(pillTimer);\n pillTimer = setTimeout(() => scanPills(doc), 600);\n };\n pillObserver = new MutationObserver((records) => {\n // Our own attribute writes must not re-trigger the scan.\n if (records.every((r) => r.type === \"attributes\" && r.attributeName === \"data-matrx-pill-inset-warning\")) return;\n schedule();\n });\n const begin = () => {\n pillObserver?.observe(doc.body, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: [\"class\", \"style\", \"data-matrx-pill-inset-warning\"] });\n schedule();\n };\n if (doc.body) begin();\n else doc.addEventListener(\"DOMContentLoaded\", begin, { once: true });\n}\n","// THE LAYOUT SCALE (0.62.4). The dev guards (pill guard, tap-target guard) judge spacing, ink\n// balance and width in LAYOUT pixels — the numbers a stylesheet writes. `getBoundingClientRect`\n// returns SCREEN pixels, so inside a CSS-transformed (zoomed) container — every Board tile at\n// overview zoom — a correct 11px gap read 5.3px at 0.48 and warned falsely. The effective scale\n// is the ratio of an element's drawn width to its layout width (`offsetWidth`, which ignores\n// transforms), taken from the nearest ancestor-or-self that has a box. 1 when no engine reports\n// layout (jsdom) or the ratio is within 2% of 1, so a real violation at scale 1 reads unchanged.\n\nexport function layoutScale(el: Element | null): number {\n for (let n: Element | null = el; n; n = n.parentElement) {\n const w = (n as HTMLElement).offsetWidth;\n if (!w) continue;\n const drawn = n.getBoundingClientRect().width;\n if (!(drawn > 0)) continue;\n const s = drawn / w;\n if (!Number.isFinite(s) || s <= 0) return 1;\n return Math.abs(s - 1) < 0.02 ? 1 : s;\n }\n return 1;\n}\n","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\n\n/** The surface a tap group sits on. \"glass\" floats over moving content; \"solid\" is a page, card,\n * toast or a header row that is itself a solid band. */\nexport type TapSurfaceKind = \"glass\" | \"solid\";\n\n// Shared through a Symbol.for slot on globalThis (like the default-variant context): the `.` and\n// `./buttons` dist bundles each inline this module, and a provider rendered by one must reach\n// buttons rendered by the other.\nconst SLOT = Symbol.for(\"@ai-matrx/tap-target:surface\");\ntype GlobalWithSlot = typeof globalThis & { [SLOT]?: ReturnType<typeof createContext<TapSurfaceKind>> };\nconst TapSurfaceContext = ((globalThis as GlobalWithSlot)[SLOT] ??= createContext<TapSurfaceKind>(\"glass\"));\n\n/**\n * GLASS ONLY FLOATS, declared once by the surface. A host whose header (or any region) is a solid\n * row wraps it in `<TapSurface surface=\"solid\">`; every `TapTargetButtonGroup` /\n * `TapTargetSearchGroup` inside then renders solid by itself — no per-page `surface=\"solid\"`.\n * A group's own `surface` prop still wins.\n */\nexport function TapSurface({ surface, children }: { surface: TapSurfaceKind; children: ReactNode }) {\n return <TapSurfaceContext.Provider value={surface}>{children}</TapSurfaceContext.Provider>;\n}\n\n/** The group's surface: its explicit prop, else the nearest `<TapSurface>`, else glass. */\nexport function useTapSurface(explicit: TapSurfaceKind | undefined): TapSurfaceKind {\n const inherited = useContext(TapSurfaceContext);\n return explicit ?? inherited;\n}\n","\"use client\";\n\n// THE BUILT-IN CAPABILITIES of every tap button — each one an enum or a flag,\n// never a class a caller writes. Rendering and geometry live in tap-target.css\n// (`.matrx-tap-badge`, `.matrx-tap-pressed`, `.matrx-tap-chevron`, …).\n\nimport { useEffect, type ReactNode } from \"react\";\n\nimport { MOTION_SPIN } from \"../motion\";\n\n/** Glyph color. Replaces the free-form `className`. */\nexport type TapTone = \"default\" | \"muted\" | \"primary\" | \"destructive\" | \"success\" | \"warning\" | \"info\";\n\n/** Fill of a solid button. Replaces `bgColor` / `iconColor` / hover / active. */\nexport type TapSolidTone = \"primary\" | \"destructive\" | \"success\" | \"warning\" | \"neutral\";\n\nexport const TAP_TONE_CLASS: Record<TapTone, string> = {\n default: \"text-foreground\",\n muted: \"text-muted-foreground group-hover/tap:text-foreground\",\n primary: \"text-primary-ink\",\n destructive: \"text-destructive-ink\",\n success: \"text-success-ink\",\n warning: \"text-warning-ink\",\n info: \"text-info-ink\",\n};\n\nexport const TAP_SOLID_TONE: Record<TapSolidTone, { fill: string; glyph: string }> = {\n primary: { fill: \"bg-primary group-hover/tap:bg-primary/85\", glyph: \"text-primary-foreground\" },\n destructive: { fill: \"bg-danger-fill group-hover/tap:bg-danger-fill/85\", glyph: \"text-danger-fill-foreground\" },\n success: { fill: \"bg-success-fill group-hover/tap:bg-success-fill/85\", glyph: \"text-success-fill-foreground\" },\n warning: { fill: \"bg-warning group-hover/tap:bg-warning/85\", glyph: \"text-warning-foreground\" },\n neutral: { fill: \"bg-foreground group-hover/tap:bg-foreground/85\", glyph: \"text-background\" },\n};\n\n/**\n * A keyboard shortcut: modifiers joined by \"+\", then one key —\n * \"mod+k\" (⌘ on Apple, Ctrl elsewhere), \"shift+mod+p\", \"alt+n\", \"/\", \"?\".\n */\nexport type TapShortcut = string;\n\nexport interface TapFeatureProps {\n /** Glyph color, from the system's list. */\n tone?: TapTone | undefined;\n /** A count (99+ past 99) or a dot, drawn on the pill's corner by the system. */\n badge?: number | \"dot\" | undefined;\n /** A toggle that is on (sidebar open, filter on): tinted pill + aria-pressed. */\n pressed?: boolean | undefined;\n /** Work in flight: the glyph becomes a spinner and presses are ignored. */\n loading?: boolean | undefined;\n /** Why the button cannot be used — disables it and becomes its tooltip. */\n disabledReason?: string | undefined;\n /** Keyboard shortcut that presses the button; shown in its tooltip. */\n shortcut?: TapShortcut | undefined;\n /** A menu trigger: a small chevron after the label. */\n chevron?: boolean | undefined;\n}\n\nconst IS_APPLE =\n typeof navigator !== \"undefined\" && /Mac|iPhone|iPad|iPod/.test(navigator.platform || navigator.userAgent);\n\ninterface ParsedShortcut {\n mod: boolean;\n shift: boolean;\n alt: boolean;\n key: string;\n}\n\nexport function parseShortcut(shortcut: TapShortcut): ParsedShortcut {\n const parts = shortcut.toLowerCase().split(\"+\");\n const key = parts.pop() ?? \"\";\n return { mod: parts.includes(\"mod\"), shift: parts.includes(\"shift\"), alt: parts.includes(\"alt\"), key };\n}\n\n/** \"mod+k\" → \"⌘K\" on Apple, \"Ctrl+K\" elsewhere. */\nexport function formatTapShortcut(shortcut: TapShortcut): string {\n const p = parseShortcut(shortcut);\n const key = p.key.length === 1 ? p.key.toUpperCase() : p.key[0]!.toUpperCase() + p.key.slice(1);\n if (IS_APPLE) return `${p.alt ? \"⌥\" : \"\"}${p.shift ? \"⇧\" : \"\"}${p.mod ? \"⌘\" : \"\"}${key}`;\n return [p.mod && \"Ctrl\", p.alt && \"Alt\", p.shift && \"Shift\", key].filter(Boolean).join(\"+\");\n}\n\nfunction isTyping(target: EventTarget | null): boolean {\n const el = target as HTMLElement | null;\n return !!el && (el.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName));\n}\n\nexport function matchesTapShortcut(e: KeyboardEvent, shortcut: TapShortcut): boolean {\n const p = parseShortcut(shortcut);\n if ((e.metaKey || e.ctrlKey) !== p.mod || e.altKey !== p.alt) return false;\n // \"?\" and other shifted symbols arrive with shiftKey set — only compare\n // shift for letters and named keys.\n if (/^[a-z0-9]$|^[a-z]{2,}$/.test(p.key) && e.shiftKey !== p.shift) return false;\n if (!p.mod && isTyping(e.target)) return false;\n return e.key.toLowerCase() === p.key;\n}\n\n/** Presses `node` when its shortcut is typed anywhere on the page. */\nexport function useTapShortcut(shortcut: TapShortcut | undefined, getNode: () => HTMLElement | null, enabled: boolean) {\n useEffect(() => {\n if (!shortcut || !enabled) return;\n const onKey = (e: KeyboardEvent) => {\n if (!matchesTapShortcut(e, shortcut)) return;\n const node = getNode();\n if (!node || !node.isConnected) return;\n e.preventDefault();\n node.click();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [shortcut, enabled, getNode]);\n}\n\nexport function TapBadge({ badge }: { badge: number | \"dot\" }) {\n if (badge === \"dot\") return <span aria-hidden=\"true\" className=\"matrx-tap-badge\" data-dot=\"\" />;\n if (badge <= 0) return null;\n return (\n <span aria-hidden=\"true\" className=\"matrx-tap-badge\">\n {badge > 99 ? \"99+\" : badge}\n </span>\n );\n}\n\nexport function TapSpinner({ className }: { className: string }) {\n return (\n <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2} aria-hidden=\"true\">\n <circle\n className={MOTION_SPIN}\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n strokeDasharray=\"28.27\"\n strokeDashoffset=\"9\"\n strokeLinecap=\"round\"\n style={{ transformOrigin: \"12px 12px\" }}\n />\n </svg>\n );\n}\n\nexport function TapChevron() {\n return (\n <svg\n className=\"matrx-tap-chevron\"\n aria-hidden=\"true\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\n/** Tooltip body: the label, then the shortcut as a key cap. */\nexport function tooltipBody(label: string, shortcut: TapShortcut | undefined): ReactNode {\n if (!shortcut) return label;\n return (\n <span className=\"matrx-tap-tooltip\">\n {label}\n <kbd className=\"matrx-tap-kbd\">{formatTapShortcut(shortcut)}</kbd>\n </span>\n );\n}\n","\"use client\";\n\nimport {\n cloneElement,\n forwardRef,\n isValidElement,\n useCallback,\n useRef,\n type ButtonHTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\n\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../tooltip\";\nimport { joinClassNames } from \"@ai-matrx/kit/dom\";\nimport { classNameMisuse, useTapGuardRef } from \"./tap-target-guard\";\nimport { useTapSurface } from \"./tap-surface\";\nimport {\n TAP_SOLID_TONE,\n TAP_TONE_CLASS,\n TapBadge,\n TapChevron,\n TapSpinner,\n formatTapShortcut,\n tooltipBody,\n useTapShortcut,\n type TapFeatureProps,\n type TapShortcut,\n type TapSolidTone,\n} from \"./tap-features\";\nimport {\n getTapTargetLinkComponent,\n type TapTargetLinkComponent,\n} from \"./link\";\n\nexport interface TapTargetButtonProps extends TapFeatureProps {\n icon?: React.ReactNode;\n children?: React.ReactNode;\n strokeWidth?: number | undefined;\n onClick?: (() => void) | undefined;\n className?: string | undefined;\n as?: \"button\" | \"label\" | undefined;\n htmlFor?: string | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n /**\n * When set, the tap button renders as a link instead of a button.\n * - Internal hrefs (e.g. \"/tasks\") render via the injected link component\n * (`setTapTargetLinkComponent` / the `linkComponent` prop), falling back\n * to a plain `<a>` when none is registered.\n * - External hrefs (http://, https://, mailto:, tel:) render as `<a>`\n * with `target=\"_blank\"` and `rel=\"noopener noreferrer\"` by default.\n * - When combined with `disabled`, the trigger renders as a non-navigable\n * `<span aria-disabled=\"true\">` with the same visual styling.\n */\n href?: string | undefined;\n /** Override target. Works on both internal links and external anchors. */\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n /** Override rel. Works on both internal links and external anchors. */\n rel?: string | undefined;\n /** Forwarded to the injected link component. Pass `false` to disable prefetching. */\n prefetch?: boolean | null | undefined;\n /**\n * Per-instance link component for internal hrefs — overrides the\n * module-level `setTapTargetLinkComponent` registration.\n */\n linkComponent?: TapTargetLinkComponent | undefined;\n /**\n * Tooltip text. Defaults to `ariaLabel` when omitted.\n * EVERY tap button shows a tooltip (owner ruling 2026-10-01). `false` no\n * longer hides it: it renders the tooltip through `title` (the provider's\n * title takeover draws the same surface) — for a button nested inside\n * another `asChild` trigger, where the Tooltip wrapper cannot sit.\n */\n tooltip?: string | false | undefined;\n /** Tooltip placement. Defaults to \"top\". */\n tooltipSide?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n /** Tooltip alignment along its side. Defaults to \"center\". */\n tooltipAlign?: \"start\" | \"center\" | \"end\" | undefined;\n /**\n * Visible caption rendered inline after the icon (`[icon Label]`).\n * Widens the pill automatically. Tooltip defaults to off when set — the\n * label is self-describing. Visible text becomes the accessible name.\n */\n label?: string | undefined;\n /**\n * Collapse an icon + caption pill to its icon-only 44px tap target below\n * the `sm` breakpoint. The caption and inline geometry return at `sm+`;\n * `ariaLabel` (falling back to `label`) remains the accessible name.\n */\n mobileIconOnly?: boolean | undefined;\n}\n\nexport interface TapTargetButtonSolidProps extends Omit<TapTargetButtonProps, \"tone\"> {\n /** The fill, from the system's list. Replaces bgColor / iconColor / hover / active. */\n tone?: TapSolidTone | undefined;\n bgColor?: string | undefined;\n iconColor?: string | undefined;\n hoverBgColor?: string | undefined;\n /**\n * Press-state background. Defaults to `group-active/tap:brightness-90` (the\n * BOX is what is pressed — its touch area included), which works on\n * any color. Override when using a custom `bgColor` that should darken to a\n * specific shade on press (e.g. `group-active/tap:bg-primary/60`).\n */\n activeBgColor?: string | undefined;\n}\n\n/** Native button attributes a tap button accepts — everything except `style`:\n * a tap button's geometry is the system's, never the caller's. */\nexport type TapTargetNativeProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"style\">;\n\nconst EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;\n\n// Geometry + press feedback + tap hygiene are the SINGLE SOURCE OF TRUTH in\n// the shipped stylesheet (the `.matrx-tap-*` family in styles.css — import\n// \"@ai-matrx/tap-target/styles.css\" once at app root). This component only\n// picks the right class and layers each variant's decoration on top.\nconst TAP_OUTER_CLASS = \"matrx-tap-target group group/tap\";\nconst TAP_GROUP_OUTER_CLASS = \"matrx-tap-target matrx-tap-target-sm group group/tap\";\n\nfunction IconContent({\n icon,\n children,\n strokeWidth = 2,\n className,\n}: Pick<\n TapTargetButtonProps,\n \"icon\" | \"children\" | \"strokeWidth\" | \"className\"\n>) {\n if (icon) {\n if (isValidElement<{ className?: string }>(icon)) {\n return cloneElement(icon, {\n className: joinClassNames(className, icon.props.className),\n });\n }\n return <span className={className}>{icon}</span>;\n }\n return (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n {children}\n </svg>\n );\n}\n\ntype TapTargetSize = \"default\" | \"sm\";\n\nfunction resolveTapGeometry(\n label: string | undefined,\n size: TapTargetSize,\n mobileIconOnly: boolean,\n) {\n const inline = Boolean(label);\n if (size === \"sm\") {\n return {\n outerClassName:\n inline && mobileIconOnly\n ? \"matrx-tap-target matrx-tap-target-sm matrx-tap-target-mobile-icon-only-sm group group/tap\"\n : inline\n ? \"matrx-tap-target matrx-tap-target-sm matrx-tap-target-inline-sm group group/tap\"\n : TAP_GROUP_OUTER_CLASS,\n inlineModifier: mobileIconOnly\n ? \"matrx-tap-pill-mobile-icon-only-sm\"\n : \"matrx-tap-pill-inline-sm\",\n };\n }\n return {\n outerClassName:\n inline && mobileIconOnly\n ? `${TAP_OUTER_CLASS} matrx-tap-target-mobile-icon-only`\n : inline\n ? `${TAP_OUTER_CLASS} matrx-tap-target-inline`\n : TAP_OUTER_CLASS,\n inlineModifier: mobileIconOnly\n ? \"matrx-tap-pill-mobile-icon-only\"\n : \"matrx-tap-pill-inline\",\n };\n}\n\nfunction buildTapInner({\n label,\n pillClassName,\n iconClassName,\n labelClassName,\n inlineModifier,\n icon,\n children,\n strokeWidth = 2,\n loading,\n chevron,\n}: {\n label?: string | undefined;\n pillClassName: string;\n iconClassName: string;\n labelClassName?: string | undefined;\n inlineModifier: string;\n icon?: React.ReactNode;\n children?: React.ReactNode;\n strokeWidth?: number | undefined;\n loading?: boolean | undefined;\n chevron?: boolean | undefined;\n}) {\n const iconEl = loading ? (\n <TapSpinner className={iconClassName} />\n ) : (\n <IconContent\n icon={icon}\n strokeWidth={strokeWidth}\n className={iconClassName}\n >\n {children}\n </IconContent>\n );\n const pillClasses = label\n ? `${pillClassName} ${inlineModifier}`.trim()\n : pillClassName;\n\n if (!label) {\n return <div className={pillClasses}>{iconEl}</div>;\n }\n\n return (\n <div className={pillClasses}>\n {iconEl}\n <span className={labelClassName ?? \"matrx-tap-label\"}>{label}</span>\n {chevron ? <TapChevron /> : null}\n </div>\n );\n}\n\ninterface RenderTapTargetArgs extends Pick<\n TapTargetButtonProps,\n | \"icon\"\n | \"children\"\n | \"strokeWidth\"\n | \"label\"\n | \"mobileIconOnly\"\n | \"onClick\"\n | \"as\"\n | \"htmlFor\"\n | \"ariaLabel\"\n | \"disabled\"\n | \"href\"\n | \"target\"\n | \"rel\"\n | \"prefetch\"\n | \"linkComponent\"\n | \"tooltip\"\n | \"tooltipSide\"\n | \"tooltipAlign\"\n> {\n size?: TapTargetSize;\n /** The caller's raw `className` (the glyph color) — checked by the guard. */\n colorClassName?: string | undefined;\n pillClassName: string;\n iconClassName: string;\n labelClassName?: string | undefined;\n rest?: (TapTargetNativeProps & TapFeatureProps) | undefined;\n buttonRef?: Ref<HTMLButtonElement> | undefined;\n}\n\n// A hook (it carries the guard ref); every variant calls it exactly once.\nfunction useTapTarget({\n size = \"default\",\n colorClassName,\n pillClassName,\n iconClassName,\n labelClassName,\n icon,\n children,\n strokeWidth,\n label,\n mobileIconOnly = false,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n rest,\n buttonRef,\n}: RenderTapTargetArgs): ReactElement {\n const {\n tone,\n badge,\n pressed,\n loading,\n disabledReason,\n shortcut,\n chevron,\n ...nativeRest\n } = rest ?? {};\n const isDisabled = Boolean(disabled || disabledReason);\n // FORCED TOOLTIPS: the text is the reason, an explicit tooltip, the\n // accessible name, or the label — and a button with none is a defect.\n const tipText =\n disabledReason || (typeof tooltip === \"string\" && tooltip ? tooltip : undefined) || ariaLabel || label;\n const titleMode = tooltip === false;\n const propViolation =\n (tipText ? null : \"every tap button needs a tooltip — pass ariaLabel\") ??\n classNameMisuse(colorClassName ?? nativeRest.className) ??\n ((nativeRest as { style?: unknown }).style ? \"style is not supported on a tap button\" : null);\n const guardRef = useTapGuardRef<HTMLElement>(\n buttonRef as Ref<HTMLElement> | undefined,\n propViolation,\n );\n const nodeRef = useRef<HTMLElement | null>(null);\n const triggerRef = useCallback(\n (node: HTMLElement | null) => {\n nodeRef.current = node;\n guardRef(node);\n },\n [guardRef],\n );\n const getNode = useCallback(() => nodeRef.current, []);\n useTapShortcut(shortcut, getNode, !isDisabled && !loading);\n\n // Tone (or a pressed toggle) owns the glyph and label color.\n const toneColor = tone ? TAP_TONE_CLASS[tone] : pressed && !colorClassName ? TAP_TONE_CLASS.primary : null;\n if (toneColor) {\n iconClassName = `matrx-tap-icon ${toneColor}`;\n labelClassName = `matrx-tap-label ${toneColor}`;\n }\n if (pressed) pillClassName = `${pillClassName} matrx-tap-pressed`;\n const { outerClassName, inlineModifier } = resolveTapGeometry(\n label,\n size,\n mobileIconOnly,\n );\n const responsiveLabelClassName = mobileIconOnly\n ? `${labelClassName ?? \"matrx-tap-label\"} matrx-tap-label-mobile-icon-only`\n : labelClassName;\n const inner = buildTapInner({\n label,\n pillClassName,\n iconClassName,\n labelClassName: responsiveLabelClassName,\n inlineModifier: label ? inlineModifier : \"\",\n icon,\n children,\n strokeWidth,\n loading,\n chevron,\n });\n const triggerAriaLabel =\n label && !mobileIconOnly ? undefined : (ariaLabel ?? label);\n const trigger = renderTrigger({\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n as,\n htmlFor,\n onClick: loading ? undefined : onClick,\n ariaLabel: triggerAriaLabel,\n disabled: isDisabled,\n outerClassName,\n title: titleMode && tipText ? (shortcut ? `${tipText} (${formatTapShortcut(shortcut)})` : tipText) : undefined,\n children: (\n <>\n {inner}\n {badge !== undefined ? <TapBadge badge={badge} /> : null}\n </>\n ),\n rest: {\n ...nativeRest,\n ...(pressed !== undefined ? { \"aria-pressed\": pressed } : {}),\n ...(loading ? { \"aria-busy\": true } : {}),\n ...(shortcut ? { \"aria-keyshortcuts\": shortcut.replace(/mod/i, \"Meta\") } : {}),\n },\n triggerRef,\n });\n if (titleMode || !tipText) return trigger;\n return withTooltip(trigger, {\n tooltip: tipText,\n ariaLabel: tipText,\n disabled: isDisabled,\n tooltipSide,\n tooltipAlign,\n shortcut,\n });\n}\n\ninterface RenderTriggerArgs {\n href?: string | undefined;\n target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\" | undefined;\n rel?: string | undefined;\n prefetch?: boolean | null | undefined;\n linkComponent?: TapTargetLinkComponent | undefined;\n as?: \"button\" | \"label\" | undefined;\n htmlFor?: string | undefined;\n onClick?: (() => void) | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n outerClassName: string;\n children: ReactNode;\n rest?: ButtonHTMLAttributes<HTMLButtonElement> | undefined;\n triggerRef: Ref<HTMLElement>;\n /** Tooltip text drawn through `title` (tooltip={false}: a nested trigger). */\n title?: string | undefined;\n}\n\n/**\n * Resolves the correct trigger element based on the props passed.\n *\n * - `href` + `disabled` → unclickable `<span aria-disabled>`\n * - `href` matching `http(s):|mailto:|tel:` → `<a target=\"_blank\" rel=\"noopener noreferrer\">`\n * - `href` (internal) → the injected link component (per-instance\n * `linkComponent` prop, else `setTapTargetLinkComponent` registration),\n * falling back to a plain `<a>` when none is registered\n * - `as=\"label\"` → `<label htmlFor=...>`\n * - default → `<button>`\n */\nfunction renderTrigger({\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n as,\n htmlFor,\n onClick,\n ariaLabel,\n disabled,\n outerClassName,\n children,\n rest,\n triggerRef,\n title,\n}: RenderTriggerArgs): ReactElement {\n const { style: _style, ...restWithoutStyle } = rest ?? {};\n if (disabled && href) {\n return (\n <span\n ref={triggerRef}\n aria-disabled=\"true\"\n aria-label={ariaLabel}\n title={title}\n className={`${outerClassName} opacity-40`}\n >\n {children}\n </span>\n );\n }\n if (href) {\n const isExternal = EXTERNAL_RE.test(href);\n if (isExternal) {\n return (\n <a\n ref={triggerRef as Ref<HTMLAnchorElement>}\n href={href}\n target={target ?? \"_blank\"}\n rel={rel ?? \"noopener noreferrer\"}\n aria-label={ariaLabel}\n title={title}\n className={outerClassName}\n >\n {children}\n </a>\n );\n }\n const Link = linkComponent ?? getTapTargetLinkComponent();\n if (Link) {\n return (\n <Link\n ref={triggerRef as Ref<HTMLAnchorElement>}\n href={href}\n target={target}\n rel={rel}\n prefetch={prefetch}\n aria-label={ariaLabel}\n title={title}\n className={outerClassName}\n >\n {children}\n </Link>\n );\n }\n // No link component registered — plain <a>. `prefetch` is a router hint,\n // not a DOM attribute, so it is deliberately dropped here.\n return (\n <a\n ref={triggerRef as Ref<HTMLAnchorElement>}\n href={href}\n target={target}\n rel={rel}\n aria-label={ariaLabel}\n title={title}\n className={outerClassName}\n >\n {children}\n </a>\n );\n }\n if (as === \"label\") {\n return (\n <label\n ref={triggerRef as Ref<HTMLLabelElement>}\n htmlFor={htmlFor}\n aria-label={ariaLabel}\n title={title}\n className={outerClassName}\n >\n {children}\n </label>\n );\n }\n return (\n <button\n ref={triggerRef as Ref<HTMLButtonElement>}\n type=\"button\"\n onClick={onClick}\n aria-label={ariaLabel}\n title={title}\n disabled={disabled}\n {...restWithoutStyle}\n className={outerClassName}\n >\n {children}\n </button>\n );\n}\n\n/**\n * Wraps a trigger element in a Tooltip when a tooltip label is available.\n * Falls back to `ariaLabel` when `tooltip` is not explicitly set. If both\n * are absent (or `tooltip === false`), the trigger is returned unwrapped.\n */\nfunction withTooltip(\n trigger: ReactElement,\n {\n tooltip,\n ariaLabel,\n disabled,\n tooltipSide = \"top\",\n tooltipAlign = \"center\",\n shortcut,\n }: {\n tooltip?: string | false | undefined;\n ariaLabel?: string | undefined;\n disabled?: boolean | undefined;\n tooltipSide?: \"top\" | \"right\" | \"bottom\" | \"left\" | undefined;\n tooltipAlign?: \"start\" | \"center\" | \"end\" | undefined;\n shortcut?: TapShortcut | undefined;\n },\n): ReactElement {\n if (tooltip === false) return trigger;\n const label =\n typeof tooltip === \"string\" && tooltip.length > 0 ? tooltip : ariaLabel;\n if (!label) return trigger;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {disabled ? (\n // Radix Tooltip triggers need a hoverable element; a disabled button\n // does not dispatch pointer events, so we wrap in a span for the\n // trigger target while keeping the disabled visual state.\n <span className=\"inline-flex\">{trigger}</span>\n ) : (\n trigger\n )}\n </TooltipTrigger>\n <TooltipContent side={tooltipSide} align={tooltipAlign}>\n {tooltipBody(label, shortcut)}\n </TooltipContent>\n </Tooltip>\n );\n}\n\n// To resize/retune every tap button, edit styles.css — not here.\n\nexport const TapTargetButton = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & TapTargetNativeProps\n>(function TapTargetButton(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return useTapTarget({\n colorClassName: className,\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: \"matrx-tap-pill matrx-glass-thin-border\",\n iconClassName: `matrx-tap-icon ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport const TapTargetButtonTransparent = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & TapTargetNativeProps\n>(function TapTargetButtonTransparent(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return useTapTarget({\n colorClassName: className,\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName:\n \"matrx-tap-pill group-hover/tap:bg-muted group-active/tap:bg-muted-foreground/15\",\n iconClassName: `matrx-tap-icon ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\n/** Outline pill — a plain 1px border, no fill, no blur, no shadow. Glass only\n * reads as glass over something you can see through; on an opaque card or\n * header use THIS. Same colors as the classic square \"+\": border-border,\n * muted glyph, primary border + foreground glyph on hover. */\nexport const TapTargetButtonOutline = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & TapTargetNativeProps\n>(function TapTargetButtonOutline(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color =\n className ?? \"text-muted-foreground group-hover/tap:text-foreground\";\n return useTapTarget({\n colorClassName: className,\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName:\n \"matrx-tap-pill border border-border bg-transparent transition-colors group-hover/tap:border-primary/60 group-active/tap:bg-muted\",\n iconClassName: `matrx-tap-icon ${color}`,\n labelClassName: `matrx-tap-label ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport const TapTargetButtonSolid = forwardRef<\n HTMLButtonElement,\n TapTargetButtonSolidProps & TapTargetNativeProps\n>(function TapTargetButtonSolid(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tone,\n bgColor,\n iconColor,\n hoverBgColor,\n activeBgColor,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n return useTapTarget({\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...solidClasses(tone, bgColor, iconColor, hoverBgColor, activeBgColor),\n rest,\n buttonRef: ref,\n });\n});\n\n// `tone` is the system's fill; the four color strings are the pre-tone API,\n// accepted only until their last callers move to `tone`. `matrx-tap-solid` marks the\n// filled pill so the stylesheet can give a DISABLED solid the system's disabled token\n// (muted fill + --disabled-foreground glyph) instead of a 40%-opacity ghost of its fill.\nfunction solidClasses(\n tone: TapSolidTone | undefined,\n bgColor: string | undefined,\n iconColor: string | undefined,\n hoverBgColor: string | undefined,\n activeBgColor: string | undefined,\n) {\n const legacy = !tone && (bgColor || iconColor || hoverBgColor || activeBgColor);\n if (!legacy) {\n const t = TAP_SOLID_TONE[tone ?? \"primary\"];\n return {\n pillClassName: `matrx-tap-pill matrx-tap-solid ${t.fill} ${t.glyph} group-active/tap:brightness-90`,\n iconClassName: `matrx-tap-icon ${t.glyph}`,\n labelClassName: `matrx-tap-label ${t.glyph}`,\n };\n }\n const glyph = iconColor ?? \"text-primary-foreground\";\n return {\n pillClassName: `matrx-tap-pill matrx-tap-solid ${bgColor ?? \"bg-primary\"} ${glyph} ${hoverBgColor ?? \"group-hover/tap:bg-primary/80\"} ${activeBgColor ?? \"group-active/tap:brightness-90\"}`,\n iconClassName: `matrx-tap-icon ${glyph}`,\n labelClassName: `matrx-tap-label ${glyph}`,\n };\n}\n\n/** Solid destructive pill — delete/remove actions. White-on-red like the\n * primary solid is white-on-blue. Use THIS, never hand-pass bg-destructive\n * with the default (dark) icon color. */\nexport const TapTargetButtonDestructive = forwardRef<\n HTMLButtonElement,\n TapTargetButtonSolidProps & TapTargetNativeProps\n>(function TapTargetButtonDestructive({ tone = \"destructive\", ...rest }, ref) {\n return <TapTargetButtonSolid ref={ref} tone={tone} {...rest} />;\n});\n\nexport const TapTargetButtonForGroup = forwardRef<\n HTMLButtonElement,\n TapTargetButtonProps & TapTargetNativeProps\n>(function TapTargetButtonForGroup(\n {\n icon,\n children,\n strokeWidth = 2,\n onClick,\n className,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n ...rest\n },\n ref,\n) {\n const color = className ?? \"text-foreground\";\n return useTapTarget({\n colorClassName: className,\n size: \"sm\",\n icon,\n children,\n strokeWidth,\n onClick,\n as,\n htmlFor,\n ariaLabel,\n disabled,\n href,\n target,\n rel,\n prefetch,\n linkComponent,\n tooltip,\n tooltipSide,\n tooltipAlign,\n label,\n mobileIconOnly,\n pillClassName: \"matrx-tap-pill matrx-tap-pill-sm matrx-glass-interactive\",\n iconClassName: `matrx-tap-icon ${color}`,\n labelClassName: `matrx-tap-label ${color}`,\n rest,\n buttonRef: ref,\n });\n});\n\nexport function TapTargetButtonGroup({\n children,\n className,\n surface: surfaceProp,\n}: {\n children: React.ReactNode;\n className?: string | undefined;\n /**\n * GLASS ONLY FLOATS (owner rule, 2026-10-02): glass belongs on a bar that\n * floats over scrolling content or a see-through plane. On a solid surface\n * (a page, a card, a toast, a table toolbar) use `\"solid\"`: a muted track,\n * no glass stroke, the same geometry.\n */\n surface?: \"glass\" | \"solid\" | undefined;\n}) {\n // Geometry (height, the half-gap outside the capsule, the capsule itself)\n // is `.matrx-tap-group*` in tap-target.css.\n const surface = useTapSurface(surfaceProp);\n return (\n <div\n className={className ? `matrx-tap-group ${className}` : \"matrx-tap-group\"}\n data-surface={surface}\n >\n <div\n className={\n surface === \"solid\"\n ? \"matrx-tap-group-capsule matrx-tap-group-capsule-solid\"\n : \"matrx-tap-group-capsule matrx-glass-thin-border\"\n }\n />\n <div className=\"matrx-tap-group-row\">{children}</div>\n </div>\n );\n}\n"],"mappings":"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","names":["half","jsx","useCallback","useRef","jsx","jsxs","useRef","useCallback","TapTargetButton","TapTargetButtonTransparent","TapTargetButtonOutline","TapTargetButtonSolid","TapTargetButtonDestructive","TapTargetButtonForGroup"]}