@aceshooting/lyra-ui 13.0.1 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/custom-elements.json +1 -1
  3. package/dist/cli/migration-contract.json +1 -1
  4. package/dist/components/agent-tools/activity-feed/activity-feed.class.d.ts +23 -15
  5. package/dist/components/agent-tools/activity-feed/activity-feed.class.js +9 -6
  6. package/dist/components/agent-tools/agent-trace/agent-trace.class.d.ts +12 -3
  7. package/dist/components/agent-tools/agent-trace/agent-trace.class.js +2 -1
  8. package/dist/components/agent-tools/approval-queue/approval-queue.class.d.ts +4 -2
  9. package/dist/components/agent-tools/approval-queue/approval-queue.class.js +1 -1
  10. package/dist/components/agent-tools/artifact-panel/artifact-panel.styles.js +1 -1
  11. package/dist/components/agent-tools/prompt-studio/prompt-studio.class.d.ts +1 -1
  12. package/dist/components/agent-tools/prompt-studio/prompt-studio.class.js +7 -7
  13. package/dist/components/agent-tools/schema-viewer/schema-viewer.class.d.ts +5 -5
  14. package/dist/components/agent-tools/schema-viewer/schema-viewer.class.js +23 -10
  15. package/dist/components/agent-tools/span-waterfall/span-waterfall.class.d.ts +13 -6
  16. package/dist/components/agent-tools/span-waterfall/span-waterfall.class.js +3 -3
  17. package/dist/components/agent-tools/span-waterfall/span-waterfall.styles.js +1 -1
  18. package/dist/components/agent-tools/stack-trace/stack-trace-parse.js +3 -3
  19. package/dist/components/agent-tools/subagent-panel/subagent-panel.class.js +1 -1
  20. package/dist/components/agent-tools/subagent-panel/subagent-panel.styles.js +1 -1
  21. package/dist/components/agent-tools/task-list/task-list.class.d.ts +1 -2
  22. package/dist/components/agent-tools/task-list/task-list.class.js +2 -2
  23. package/dist/components/agent-tools/terminal/terminal.class.d.ts +10 -1
  24. package/dist/components/agent-tools/terminal/terminal.class.js +3 -3
  25. package/dist/components/agent-tools/terminal/terminal.styles.js +1 -1
  26. package/dist/components/agent-tools/test-results/test-results.class.d.ts +4 -2
  27. package/dist/components/agent-tools/test-results/test-results.class.js +2 -2
  28. package/dist/components/agent-tools/thinking-panel/thinking-panel.class.d.ts +2 -0
  29. package/dist/components/agent-tools/thinking-panel/thinking-panel.styles.js +1 -1
  30. package/dist/components/agent-tools/tool-approval-dialog/tool-approval-dialog.class.js +1 -1
  31. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.js +1 -1
  32. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +3 -2
  33. package/dist/components/agent-tools/tool-param-form/tool-param-form.d.ts +1 -1
  34. package/dist/components/agent-tools/tool-param-form/tool-param-form.js +1 -1
  35. package/dist/components/agent-tools/tool-result-dialog/tool-result-dialog.styles.js +1 -1
  36. package/dist/components/agent-tools/tool-result-view/registry.d.ts +2 -1
  37. package/dist/components/agent-tools/tool-result-view/tool-result-view.class.d.ts +1 -1
  38. package/dist/components/agent-tools/tool-result-view/tool-result-view.class.js +1 -1
  39. package/dist/components/agent-tools/tool-select-dialog/tool-select-dialog.class.d.ts +18 -12
  40. package/dist/components/agent-tools/tool-select-dialog/tool-select-dialog.class.js +6 -6
  41. package/dist/components/agent-tools/tool-timeline/tool-timeline.class.d.ts +9 -3
  42. package/dist/components/agent-tools/tool-timeline/tool-timeline.class.js +1 -1
  43. package/dist/components/agent-tools/trace-tree/span.js +1 -1
  44. package/dist/components/agent-tools/trace-tree/trace-tree.styles.js +1 -1
  45. package/dist/components/charts/chart/box-plot.class.d.ts +10 -3
  46. package/dist/components/charts/chart/box-plot.class.js +9 -9
  47. package/dist/components/charts/chart/box-plot.styles.js +1 -1
  48. package/dist/components/charts/chart/chart-core-loader.js +1 -1
  49. package/dist/components/charts/chart/chart-feature-loader.js +1 -1
  50. package/dist/components/charts/chart/chart-preload.d.ts +1 -1
  51. package/dist/components/charts/chart/chart-preload.js +1 -1
  52. package/dist/components/charts/chart/chart.class.d.ts +27 -9
  53. package/dist/components/charts/chart/chart.class.js +23 -14
  54. package/dist/components/charts/chart/chart.styles.js +1 -1
  55. package/dist/components/charts/chart/histogram-bin.js +1 -1
  56. package/dist/components/charts/chart/lite-chart.class.js +7 -3
  57. package/dist/components/charts/chart/lite-chart.styles.js +1 -1
  58. package/dist/components/conversation/agent-workspace/agent-workspace.class.d.ts +1 -1
  59. package/dist/components/conversation/agent-workspace/agent-workspace.class.js +2 -2
  60. package/dist/components/conversation/audio-visualizer/audio-visualizer.class.d.ts +10 -5
  61. package/dist/components/conversation/audio-visualizer/audio-visualizer.class.js +1 -1
  62. package/dist/components/conversation/branch-picker/branch-picker.class.d.ts +4 -2
  63. package/dist/components/conversation/branch-picker/branch-picker.class.js +1 -1
  64. package/dist/components/conversation/branch-picker/branch-picker.styles.js +1 -1
  65. package/dist/components/conversation/chat-composer/chat-composer.class.d.ts +6 -2
  66. package/dist/components/conversation/chat-composer/chat-composer.class.js +3 -3
  67. package/dist/components/conversation/chat-composer/chat-composer.styles.js +1 -1
  68. package/dist/components/conversation/chat-message/chat-message.class.js +2 -2
  69. package/dist/components/conversation/chat-message/chat-message.styles.js +1 -1
  70. package/dist/components/conversation/chat-viewport/chat-viewport.styles.js +1 -1
  71. package/dist/components/conversation/code-block/code-block-shared.js +1 -1
  72. package/dist/components/conversation/code-block/code-block.styles.js +1 -1
  73. package/dist/components/conversation/code-block/code-loader.d.ts +1 -1
  74. package/dist/components/conversation/code-block/code-loader.js +1 -1
  75. package/dist/components/conversation/code-block/shiki-types.js +1 -1
  76. package/dist/components/conversation/conversation-item/conversation-item.styles.js +1 -1
  77. package/dist/components/conversation/generation-metrics/generation-metrics.styles.js +1 -1
  78. package/dist/components/conversation/markdown/katex-loader.d.ts +4 -4
  79. package/dist/components/conversation/markdown/katex-loader.js +1 -1
  80. package/dist/components/conversation/markdown/markdown-base.class.js +1 -1
  81. package/dist/components/conversation/markdown/markdown-loader.d.ts +1 -1
  82. package/dist/components/conversation/markdown/markdown-loader.js +1 -1
  83. package/dist/components/conversation/markdown/markdown-shared.d.ts +6 -1
  84. package/dist/components/conversation/markdown/markdown-shared.js +5 -4
  85. package/dist/components/conversation/message-actions/message-actions.class.d.ts +16 -3
  86. package/dist/components/conversation/message-actions/message-actions.class.js +2 -2
  87. package/dist/components/conversation/message-actions/message-actions.styles.js +1 -1
  88. package/dist/components/conversation/message-actions/toolbar-actions.d.ts +3 -1
  89. package/dist/components/conversation/message-actions/toolbar-actions.js +1 -1
  90. package/dist/components/conversation/message-feedback/message-feedback.class.d.ts +38 -15
  91. package/dist/components/conversation/message-feedback/message-feedback.class.js +7 -3
  92. package/dist/components/conversation/message-feedback/message-feedback.styles.js +1 -1
  93. package/dist/components/conversation/message-parts/message-parts.class.d.ts +7 -4
  94. package/dist/components/conversation/message-parts/message-parts.class.js +2 -2
  95. package/dist/components/conversation/message-parts/message-parts.styles.js +1 -1
  96. package/dist/components/conversation/model-select/model-select.class.d.ts +5 -2
  97. package/dist/components/conversation/model-select/model-select.class.js +5 -2
  98. package/dist/components/conversation/model-settings-panel/model-settings-panel.class.d.ts +3 -5
  99. package/dist/components/conversation/model-settings-panel/model-settings-panel.class.js +2 -1
  100. package/dist/components/conversation/prompt-input/prompt-input.class.d.ts +9 -2
  101. package/dist/components/conversation/prompt-input/prompt-input.class.js +3 -3
  102. package/dist/components/conversation/prompt-input/prompt-input.styles.js +1 -1
  103. package/dist/components/conversation/prompt-queue/prompt-queue.class.d.ts +20 -4
  104. package/dist/components/conversation/prompt-queue/prompt-queue.class.js +1 -1
  105. package/dist/components/conversation/prompt-queue/prompt-queue.styles.js +1 -1
  106. package/dist/components/conversation/push-to-talk/push-to-talk.class.d.ts +17 -8
  107. package/dist/components/conversation/push-to-talk/push-to-talk.class.js +1 -1
  108. package/dist/components/conversation/push-to-talk/push-to-talk.styles.js +1 -1
  109. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.d.ts +6 -3
  110. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
  111. package/dist/components/conversation/selection-toolbar/selection-toolbar.styles.js +1 -1
  112. package/dist/components/conversation/thread-list/thread-list.class.d.ts +14 -4
  113. package/dist/components/conversation/thread-list/thread-list.class.js +11 -11
  114. package/dist/components/conversation/thread-list/thread-list.styles.js +1 -1
  115. package/dist/components/conversation/transcript-feed/transcript-feed.styles.js +1 -1
  116. package/dist/components/conversation/voice-picker/voice-picker.class.d.ts +12 -4
  117. package/dist/components/conversation/voice-picker/voice-picker.class.js +5 -2
  118. package/dist/components/conversation/voice-picker/voice-picker.styles.js +1 -1
  119. package/dist/components/data/calendar/calendar.class.d.ts +12 -4
  120. package/dist/components/data/calendar/calendar.class.js +2 -2
  121. package/dist/components/data/calendar/calendar.styles.js +1 -1
  122. package/dist/components/data/context-meter/context-meter.class.d.ts +3 -1
  123. package/dist/components/data/context-meter/context-meter.class.js +3 -3
  124. package/dist/components/data/data-grid/data-grid.class.d.ts +45 -4
  125. package/dist/components/data/data-grid/data-grid.class.js +25 -11
  126. package/dist/components/data/data-grid/data-grid.styles.js +1 -1
  127. package/dist/components/data/document-library/document-library.class.js +1 -1
  128. package/dist/components/data/env-list/env-list.class.js +1 -1
  129. package/dist/components/data/flow-canvas/flow-canvas.class.d.ts +19 -12
  130. package/dist/components/data/flow-canvas/flow-canvas.class.js +1 -2
  131. package/dist/components/data/flow-controls/flow-controls.styles.js +1 -1
  132. package/dist/components/data/flow-run-status/flow-run-status.class.js +1 -1
  133. package/dist/components/data/gauge/gauge.class.js +1 -1
  134. package/dist/components/data/graph-query-builder/graph-query-builder.styles.js +1 -1
  135. package/dist/components/data/heatmap/heatmap.class.js +1 -1
  136. package/dist/components/data/sequence-strip/sequence-strip.class.js +1 -1
  137. package/dist/components/data/stat/stat.class.js +1 -1
  138. package/dist/components/data/table/table.class.d.ts +10 -14
  139. package/dist/components/data/table/table.class.js +4 -3
  140. package/dist/components/data/table/table.styles.js +1 -1
  141. package/dist/components/data/timeline/timeline.class.js +1 -1
  142. package/dist/components/data/tree/tree-item.styles.js +1 -1
  143. package/dist/components/data/word-cloud/word-cloud.class.js +1 -1
  144. package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +7 -2
  145. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  146. package/dist/components/forms/code-editor/code-editor.class.d.ts +8 -4
  147. package/dist/components/forms/code-editor/code-editor.class.js +16 -5
  148. package/dist/components/forms/code-editor/code-editor.styles.js +1 -1
  149. package/dist/components/forms/color-picker/color-picker.class.d.ts +1 -1
  150. package/dist/components/forms/color-picker/color-picker.class.js +1 -1
  151. package/dist/components/forms/combobox/combobox.styles.js +1 -1
  152. package/dist/components/forms/date-picker/date-input.class.js +1 -1
  153. package/dist/components/forms/date-picker/date-picker.class.d.ts +9 -2
  154. package/dist/components/forms/date-picker/date-picker.class.js +4 -4
  155. package/dist/components/forms/date-picker/date-picker.styles.js +1 -1
  156. package/dist/components/forms/emoji-picker/emoji-data-loader.js +1 -1
  157. package/dist/components/forms/emoji-picker/emoji-picker.class.js +1 -1
  158. package/dist/components/forms/input/input.class.d.ts +11 -4
  159. package/dist/components/forms/input/input.class.js +7 -1
  160. package/dist/components/forms/input/time-input.class.d.ts +8 -2
  161. package/dist/components/forms/input/time-input.class.js +1 -1
  162. package/dist/components/forms/locale-picker/locale-picker.class.d.ts +17 -3
  163. package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
  164. package/dist/components/forms/locale-picker/locale-picker.styles.js +1 -1
  165. package/dist/components/forms/rubric-form/rubric-form.class.js +1 -1
  166. package/dist/components/forms/select/select.styles.js +1 -1
  167. package/dist/components/forms/slider/slider.class.js +1 -1
  168. package/dist/components/forms/swatch-picker/swatch-picker.class.js +1 -1
  169. package/dist/components/forms/token-input/token-input.class.js +1 -1
  170. package/dist/components/forms/token-input/token-input.styles.js +1 -1
  171. package/dist/components/layout/app-rail/app-rail.class.d.ts +6 -4
  172. package/dist/components/layout/app-rail/app-rail.class.js +4 -3
  173. package/dist/components/layout/app-rail/app-rail.styles.js +1 -1
  174. package/dist/components/layout/command-palette/command-palette.class.d.ts +2 -2
  175. package/dist/components/layout/command-palette/command-palette.class.js +1 -1
  176. package/dist/components/layout/command-palette/command-palette.styles.js +1 -1
  177. package/dist/components/layout/dashboard-grid/dashboard-grid.class.js +1 -1
  178. package/dist/components/layout/details/details.class.d.ts +13 -12
  179. package/dist/components/layout/details/details.class.js +43 -34
  180. package/dist/components/layout/details/details.styles.js +1 -1
  181. package/dist/components/layout/dock-panel/dock-panel.class.d.ts +4 -3
  182. package/dist/components/layout/dock-panel/dock-panel.class.js +2 -1
  183. package/dist/components/layout/filter-bar/filter-bar.class.js +2 -2
  184. package/dist/components/layout/menu/menu-item.class.js +2 -2
  185. package/dist/components/layout/menu/menu.class.js +1 -1
  186. package/dist/components/layout/multi-split/multi-split.class.d.ts +10 -5
  187. package/dist/components/layout/multi-split/multi-split.class.js +2 -1
  188. package/dist/components/layout/scroller/scroller.class.d.ts +4 -4
  189. package/dist/components/layout/scroller/scroller.styles.js +1 -1
  190. package/dist/components/layout/split-panel/split-panel.class.d.ts +3 -2
  191. package/dist/components/layout/split-panel/split-panel.class.js +3 -2
  192. package/dist/components/layout/tab-group/tab-group.styles.js +1 -1
  193. package/dist/components/layout/virtual-list/virtual-list.class.js +2 -2
  194. package/dist/components/layout/widget/widget.styles.js +1 -1
  195. package/dist/components/media/file-input/file-input.styles.js +1 -1
  196. package/dist/components/media/flag/flag.class.js +1 -1
  197. package/dist/components/media/lightbox/lightbox.styles.js +1 -1
  198. package/dist/components/media/map/map-loader.js +1 -1
  199. package/dist/components/media/map/map.class.d.ts +17 -31
  200. package/dist/components/media/map/map.class.js +1 -1
  201. package/dist/components/media/qr-code/qr-code-loader.js +1 -1
  202. package/dist/components/media/qr-code/qr-code.class.d.ts +5 -2
  203. package/dist/components/media/qr-code/qr-code.class.js +2 -2
  204. package/dist/components/media/sequence-playback/sequence-playback.class.d.ts +2 -2
  205. package/dist/components/media/sequence-playback/sequence-playback.class.js +1 -1
  206. package/dist/components/overlays/alert/alert.styles.js +1 -1
  207. package/dist/components/overlays/callout/callout.styles.js +1 -1
  208. package/dist/components/overlays/dialog/dialog.styles.js +1 -1
  209. package/dist/components/overlays/kbd/kbd.class.js +1 -1
  210. package/dist/components/overlays/overlay/popover.class.js +1 -1
  211. package/dist/components/overlays/overlay/tooltip.class.js +1 -1
  212. package/dist/components/overlays/rating/rating.class.js +1 -1
  213. package/dist/components/overlays/toast/toast-item.class.js +1 -1
  214. package/dist/components/retrieval/claim-evidence/claim-evidence.class.d.ts +11 -5
  215. package/dist/components/retrieval/claim-evidence/claim-evidence.class.js +3 -3
  216. package/dist/components/retrieval/graph/graph-loader.js +1 -1
  217. package/dist/components/retrieval/graph/graph.class.d.ts +1 -1
  218. package/dist/components/retrieval/graph/graph.class.js +10 -10
  219. package/dist/components/retrieval/graph-legend/graph-legend.class.d.ts +4 -2
  220. package/dist/components/retrieval/graph-legend/graph-legend.class.js +1 -1
  221. package/dist/components/retrieval/grounding-summary/grounding-summary.class.d.ts +14 -6
  222. package/dist/components/retrieval/grounding-summary/grounding-summary.class.js +7 -5
  223. package/dist/components/retrieval/knowledge-base/knowledge-base.class.d.ts +3 -2
  224. package/dist/components/retrieval/knowledge-base/knowledge-base.class.js +4 -3
  225. package/dist/components/retrieval/knowledge-base/knowledge-base.styles.js +1 -1
  226. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.d.ts +4 -1
  227. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +2 -1
  228. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.styles.js +1 -1
  229. package/dist/components/retrieval/memory-panel/memory-panel.class.d.ts +15 -6
  230. package/dist/components/retrieval/memory-panel/memory-panel.class.js +1 -1
  231. package/dist/components/retrieval/neighbor-list/neighbor-list.class.js +1 -1
  232. package/dist/components/retrieval/neighbor-list/neighbor-list.styles.js +1 -1
  233. package/dist/components/retrieval/node-palette/node-palette.class.d.ts +17 -12
  234. package/dist/components/retrieval/node-palette/node-palette.class.js +2 -2
  235. package/dist/components/retrieval/node-palette/node-palette.styles.js +1 -1
  236. package/dist/components/retrieval/path-strip/path-strip.class.js +1 -1
  237. package/dist/components/retrieval/retrieval-results/retrieval-results.class.d.ts +1 -1
  238. package/dist/components/retrieval/retrieval-results/retrieval-results.class.js +5 -5
  239. package/dist/components/retrieval/retrieval-trace/retrieval-trace.class.js +1 -1
  240. package/dist/components/retrieval/source-picker/source-picker.class.js +1 -1
  241. package/dist/components/utility/copy-button/copy-button.class.d.ts +2 -1
  242. package/dist/components/utility/copy-button/copy-button.class.js +1 -1
  243. package/dist/components/utility/diff-view/diff-view.class.d.ts +4 -1
  244. package/dist/components/utility/diff-view/diff-view.class.js +1 -1
  245. package/dist/components/utility/export-button/export-button.class.d.ts +2 -2
  246. package/dist/components/utility/export-button/export-button.class.js +1 -1
  247. package/dist/components/utility/export-button/export-button.styles.js +1 -1
  248. package/dist/components/utility/format/format-date.class.js +1 -1
  249. package/dist/components/utility/format/relative-time.class.js +1 -1
  250. package/dist/components/utility/icon/dompurify-loader.js +1 -1
  251. package/dist/components/utility/icon/icon-library.js +1 -1
  252. package/dist/components/utility/intersection-observer/intersection-observer.class.js +1 -1
  253. package/dist/components/utility/json-viewer/json-viewer.class.d.ts +3 -1
  254. package/dist/components/utility/json-viewer/json-viewer.class.js +5 -5
  255. package/dist/components/utility/known-date/known-date.class.js +1 -1
  256. package/dist/components/utility/mention-popover/mention-popover.class.d.ts +29 -44
  257. package/dist/components/utility/mention-popover/mention-popover.class.js +1 -1
  258. package/dist/components/utility/mutation-observer/mutation-observer.class.js +1 -1
  259. package/dist/components/viewers/calendar-viewer/calendar-loader.js +1 -1
  260. package/dist/components/viewers/document-compare/document-compare.class.d.ts +11 -8
  261. package/dist/components/viewers/document-compare/document-compare.class.js +2 -2
  262. package/dist/components/viewers/document-preview/document-preview.class.d.ts +4 -2
  263. package/dist/components/viewers/document-preview/document-preview.class.js +4 -4
  264. package/dist/components/viewers/document-preview/document-preview.styles.js +1 -1
  265. package/dist/components/viewers/document-viewer/document-viewer.class.d.ts +2 -0
  266. package/dist/components/viewers/document-viewer/document-viewer.styles.js +1 -1
  267. package/dist/components/viewers/docx-viewer/docx-loader.js +1 -1
  268. package/dist/components/viewers/docx-viewer/docx-viewer.class.js +1 -1
  269. package/dist/components/viewers/ebook-viewer/ebook-loader.d.ts +1 -1
  270. package/dist/components/viewers/ebook-viewer/ebook-viewer.class.d.ts +2 -2
  271. package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +1 -1
  272. package/dist/components/viewers/email-viewer/email-loader.js +1 -1
  273. package/dist/components/viewers/email-viewer/email-viewer.class.d.ts +1 -1
  274. package/dist/components/viewers/email-viewer/email-viewer.class.js +2 -2
  275. package/dist/components/viewers/html-viewer/dompurify-loader.js +1 -1
  276. package/dist/components/viewers/notebook-viewer/dompurify-loader.js +1 -1
  277. package/dist/components/viewers/pdf-viewer/pdf-loader.js +1 -1
  278. package/dist/components/viewers/pptx-viewer/pptx-loader.js +1 -1
  279. package/dist/components/viewers/spreadsheet-viewer/spreadsheet-loader.js +1 -1
  280. package/dist/components/viewers/svg-viewer/dompurify-loader.js +1 -1
  281. package/dist/components/viewers/viewer-loading.js +1 -1
  282. package/dist/components/viewers/viewer-search-limits.d.ts +2 -0
  283. package/dist/components/viewers/viewer-search-limits.js +1 -1
  284. package/dist/custom-elements-jsx.d.ts +1 -1
  285. package/dist/events.d.ts +13 -6
  286. package/dist/internal/aria-controls.d.ts +16 -13
  287. package/dist/internal/aria-controls.js +1 -1
  288. package/dist/internal/aria-reflection.js +1 -1
  289. package/dist/internal/catalog-picker.d.ts +2 -2
  290. package/dist/internal/catalog-picker.js +1 -1
  291. package/dist/internal/chart-annotation-registration.d.ts +1 -0
  292. package/dist/internal/chart-annotation-registration.js +1 -0
  293. package/dist/internal/data-descriptors.d.ts +13 -0
  294. package/dist/internal/data-descriptors.js +1 -0
  295. package/dist/internal/default-strings.generated.d.ts +1 -1
  296. package/dist/internal/default-strings.generated.js +2 -2
  297. package/dist/internal/dev-mode-attribute-warning.js +1 -1
  298. package/dist/internal/element-internals.d.ts +4 -3
  299. package/dist/internal/element-internals.js +1 -1
  300. package/dist/internal/highlight-collection.d.ts +2 -0
  301. package/dist/internal/highlight-collection.js +1 -1
  302. package/dist/internal/localization-types.d.ts +1 -1
  303. package/dist/internal/localization.js +2 -2
  304. package/dist/internal/lyra-element.d.ts +10 -1
  305. package/dist/internal/lyra-element.js +2 -1
  306. package/dist/internal/package-metadata.d.ts +1 -1
  307. package/dist/internal/package-metadata.js +1 -1
  308. package/dist/internal/papaparse-loader.js +1 -1
  309. package/dist/internal/pseudo-localization.js +1 -1
  310. package/dist/internal/safe-css.js +1 -1
  311. package/dist/internal/step-value.d.ts +6 -0
  312. package/dist/internal/step-value.js +1 -0
  313. package/dist/internal/text-quote.js +1 -1
  314. package/dist/lyra.d.ts +1 -1
  315. package/dist/svelte.d.ts +1 -1
  316. package/dist/translations/ar.js +2 -2
  317. package/dist/translations/de.js +2 -2
  318. package/dist/translations/es.js +2 -2
  319. package/dist/translations/fa.js +2 -2
  320. package/dist/translations/fr.js +2 -2
  321. package/dist/translations/he.js +2 -2
  322. package/dist/translations/ja.js +2 -2
  323. package/dist/translations/pseudo/ar-XB.js +1 -1
  324. package/dist/translations/pt-BR.js +2 -2
  325. package/dist/translations/ru.js +2 -2
  326. package/dist/translations/zh-CN.js +2 -2
  327. package/dist/vue.d.ts +1 -1
  328. package/llms/components/lr-accordion-item.md +6 -5
  329. package/llms/components/lr-accordion.md +6 -5
  330. package/llms/components/lr-activity-feed.md +6 -5
  331. package/llms/components/lr-agent-run.md +1 -1
  332. package/llms/components/lr-agent-workspace.md +3 -2
  333. package/llms/components/lr-attachment-chip.md +2 -3
  334. package/llms/components/lr-audio-visualizer.md +9 -6
  335. package/llms/components/lr-bar-chart.md +2 -2
  336. package/llms/components/lr-box-plot.md +9 -6
  337. package/llms/components/lr-bubble-chart.md +2 -2
  338. package/llms/components/lr-calendar.md +10 -4
  339. package/llms/components/lr-chart.md +11 -5
  340. package/llms/components/lr-chat-composer.md +2 -1
  341. package/llms/components/lr-chunk-inspector.md +2 -2
  342. package/llms/components/lr-code-block-core.md +4 -4
  343. package/llms/components/lr-code-block.md +10 -14
  344. package/llms/components/lr-code-editor.md +2 -0
  345. package/llms/components/lr-copy-button.md +4 -1
  346. package/llms/components/lr-data-grid.md +11 -2
  347. package/llms/components/lr-date-input.md +4 -0
  348. package/llms/components/lr-date-picker.md +5 -1
  349. package/llms/components/lr-details.md +6 -5
  350. package/llms/components/lr-diff-view.md +6 -0
  351. package/llms/components/lr-document-compare.md +6 -2
  352. package/llms/components/lr-document-preview.md +11 -3
  353. package/llms/components/lr-document-viewer.md +5 -1
  354. package/llms/components/lr-docx-viewer.md +6 -0
  355. package/llms/components/lr-doughnut-chart.md +2 -2
  356. package/llms/components/lr-ebook-viewer.md +8 -3
  357. package/llms/components/lr-email-viewer.md +5 -0
  358. package/llms/components/lr-eval-dataset.md +2 -2
  359. package/llms/components/lr-export-button.md +9 -0
  360. package/llms/components/lr-file-input.md +5 -8
  361. package/llms/components/lr-format-date.md +3 -1
  362. package/llms/components/lr-graph-legend.md +4 -2
  363. package/llms/components/lr-grounding-summary.md +8 -8
  364. package/llms/components/lr-histogram.md +2 -2
  365. package/llms/components/lr-ingestion-queue.md +1 -1
  366. package/llms/components/lr-intersection-observer.md +9 -0
  367. package/llms/components/lr-json-viewer.md +6 -1
  368. package/llms/components/lr-knowledge-base.md +10 -1
  369. package/llms/components/lr-line-chart.md +2 -2
  370. package/llms/components/lr-lite-chart.md +8 -5
  371. package/llms/components/lr-locale-picker.md +6 -0
  372. package/llms/components/lr-map.md +15 -5
  373. package/llms/components/lr-markdown.md +7 -4
  374. package/llms/components/lr-media-card.md +0 -6
  375. package/llms/components/lr-mention-popover.md +12 -10
  376. package/llms/components/lr-message-actions.md +10 -3
  377. package/llms/components/lr-message-feedback.md +20 -7
  378. package/llms/components/lr-message-parts.md +3 -1
  379. package/llms/components/lr-model-select.md +5 -2
  380. package/llms/components/lr-multi-split.md +5 -1
  381. package/llms/components/lr-mutation-observer.md +8 -0
  382. package/llms/components/lr-node-palette.md +5 -2
  383. package/llms/components/lr-pie-chart.md +2 -2
  384. package/llms/components/lr-polar-area-chart.md +2 -2
  385. package/llms/components/lr-prompt-input.md +7 -3
  386. package/llms/components/lr-prompt-queue.md +6 -0
  387. package/llms/components/lr-push-to-talk.md +5 -0
  388. package/llms/components/lr-qr-code.md +6 -0
  389. package/llms/components/lr-radar-chart.md +2 -2
  390. package/llms/components/lr-rating.md +5 -0
  391. package/llms/components/lr-relative-time.md +2 -0
  392. package/llms/components/lr-result-card.md +3 -3
  393. package/llms/components/lr-result-field.md +3 -3
  394. package/llms/components/lr-retrieval-results.md +1 -1
  395. package/llms/components/lr-scatter-chart.md +2 -2
  396. package/llms/components/lr-scroller.md +5 -5
  397. package/llms/components/lr-sequence-playback.md +1 -2
  398. package/llms/components/lr-slider.md +3 -1
  399. package/llms/components/lr-streaming-text.md +2 -3
  400. package/llms/components/lr-terminal.md +14 -5
  401. package/llms/components/lr-thinking-panel.md +3 -1
  402. package/llms/components/lr-thread-list.md +20 -1
  403. package/llms/components/lr-tool-call-chip.md +2 -2
  404. package/llms/components/lr-tool-param-form.md +2 -2
  405. package/llms/components/lr-tool-result-view.md +2 -3
  406. package/llms/components/lr-tool-select-dialog.md +2 -2
  407. package/llms/components/lr-voice-picker.md +7 -2
  408. package/llms/components/lr-widget-renderer.md +12 -13
  409. package/llms/peers.md +5 -5
  410. package/llms/shared.md +74 -63
  411. package/llms-full.txt +629 -247
  412. package/package.json +18 -13
  413. package/vscode-css-data.json +1 -1
  414. package/vscode-html-data.json +1 -1
  415. package/web-types.json +1 -1
  416. package/dist/components/viewers/docx-viewer/fixtures/minimal-docx-fixture.d.ts +0 -1
  417. package/dist/components/viewers/docx-viewer/fixtures/minimal-docx-fixture.js +0 -1
  418. package/dist/components/viewers/ebook-viewer/fixtures/minimal-epub-fixture.d.ts +0 -1
  419. package/dist/components/viewers/ebook-viewer/fixtures/minimal-epub-fixture.js +0 -1
  420. package/dist/components/viewers/spreadsheet-viewer/fixtures/minimal-xlsx-fixture.d.ts +0 -1
  421. package/dist/components/viewers/spreadsheet-viewer/fixtures/minimal-xlsx-fixture.js +0 -1
package/llms-full.txt CHANGED
@@ -62,11 +62,6 @@ introduced by the current release, it is the current package version.
62
62
  compatibility promises: once published, their public APIs receive the same full-semver protection
63
63
  as stable components until they are formally deprecated and removed.
64
64
 
65
- An experimental component graduates to stable only after its documented API, populated
66
- accessibility state, behavior in Chromium, Firefox, and WebKit, and compatibility contract pass
67
- maintainer review and release qualification. A stable component keeps that status only while those
68
- contracts remain release-blocking.
69
-
70
65
  Deprecation is explicit metadata, not an implication from status. Each deprecated component or
71
66
  member names a replacement, a deprecation version, a rationale, and the earliest permitted removal
72
67
  version. If an API is deprecated in major version M, it remains available for the complete M+1
@@ -101,8 +96,7 @@ The major-version landmarks after 9.0.0 are:
101
96
 
102
97
  - **10.0.0:** removed eligible members deprecated during 9.x and made the public-contract
103
98
  corrections listed in its changelog entry; follow that entry's per-member migration guidance.
104
- - **11.0.0:** carried no known consumer-breaking change. The major number recorded conservative
105
- public-API-gate fingerprint and generated-type churn; consumers upgrading from 10.x were not
99
+ - **11.0.0:** carried no known consumer-breaking change; consumers upgrading from 10.x were not
106
100
  expected to change code.
107
101
  - **12.0.0:** removed the inherited static `LyraElement.getPropertyDescriptor()` surface after Lit
108
102
  deprecated that finalization hook. Ordinary component consumers need no migration; only subclasses
@@ -116,10 +110,10 @@ Chromium 120+, Gecko 121+, WebKit 16.4+, and Node 20+ (ESM only; there is no Com
116
110
  Those floors are derived from platform features the source actually uses — `:dir()`, `:has()`,
117
111
  `@container`, `color-mix()`, `ElementInternals` form association — because the package ships
118
112
  untranspiled ES2022 modules with no polyfills and no build-time downleveling. There is deliberately
119
- no `browserslist` field: it would describe a build step this package does not have. CI proves the
120
- current stable build of each engine (the full suite on Chromium, a contract subset on Firefox and
121
- WebKit, on Node 20 and 22); the version floors are derived rather than tested. Raising any floor is
122
- a semver-major change. Full policy, including the known WebKit cross-shadow-selection gap and the
113
+ no `browserslist` field: it would describe a build step this package does not have. The version
114
+ floors are derived from those platform features rather than individually verified version-by-version.
115
+ Raising any floor is a semver-major change. Full policy, including the known WebKit
116
+ cross-shadow-selection gap and the
123
117
  rule for when a `@supports` fallback may be dropped:
124
118
  <https://github.com/aceshooting/lyra-ui/blob/main/docs/support-policy.md>.
125
119
 
@@ -237,12 +231,49 @@ The entry points, then:
237
231
  `@aceshooting/lyra-ui/ai` (provider-neutral data types), `@aceshooting/lyra-ui/testing`
238
232
  (happy-dom shims), `@aceshooting/lyra-ui/utilities/*` (the curated shared helpers, all documented below).
239
233
 
234
+ ### Registration-free component helpers
235
+
236
+ The following focused helpers are public, side-effect-free modules. They do not define a custom
237
+ element, so they are suitable for server code, workers, or applications that need the same data
238
+ normalization as a component without registering it:
239
+
240
+ ```ts
241
+ import {
242
+ DEFAULT_INTERNAL_PATTERNS,
243
+ parseStackTrace,
244
+ STACK_TRACE_LIMITS,
245
+ } from '@aceshooting/lyra-ui/components/agent-tools/stack-trace/stack-trace-parse.js';
246
+ import {
247
+ MAX_RENDERED_LYRA_SPANS,
248
+ normalizeLyraSpans,
249
+ } from '@aceshooting/lyra-ui/components/agent-tools/trace-tree/span.js';
250
+ import {
251
+ agentStatusMessage,
252
+ agentStatusVariant,
253
+ } from '@aceshooting/lyra-ui/components/agent-tools/agent-status-presentation.js';
254
+ import {
255
+ approvalAction,
256
+ approvalDecision,
257
+ } from '@aceshooting/lyra-ui/components/agent-tools/approval-state.js';
258
+ import { DEFAULT_WIDGET_TYPE_REGISTRY } from '@aceshooting/lyra-ui/components/conversation/widget-renderer/default-registry.js';
259
+ ```
260
+
261
+ Their companion type exports remain on those same paths: stack parsing exposes `StackFrame`,
262
+ `StackGroup`, `StackTraceParseOptions`, and `StackTraceParseResult`; span projection exposes
263
+ `LyraSpan`, `LyraSpanKind`, `LyraSpanStatus`, and `LyraSpanProjection`; status and approval helpers
264
+ expose their respective presentation and decision types. The status helpers are `agentStatusKind`,
265
+ `agentStatusLabel`, `agentStatusMessage`, `agentStatusVariant`, `isAgentStatusTerminal`, and
266
+ `isAgentStatusActive`; approval also exports `ApprovalAction` and `ApprovalDecision`; span also
267
+ exports `normalizeLyraSpanKind` and `normalizeLyraSpanStatus`; the widget registry module exports
268
+ only `DEFAULT_WIDGET_TYPE_REGISTRY`. Import a component registration entry separately when the page
269
+ also renders that component.
270
+
240
271
  ### Optional autoloader
241
272
 
242
273
  `@aceshooting/lyra-ui/autoloader.js` exports `discover(root?, options?)`, `start(root?, options?)`,
243
- and `stop()`. It contains an inventory-generated literal class-module import for every known Lyra
244
- tag, so a bundler can split each component while ordinary granular imports remain independent.
245
- Importing this entry alone has no side effect and registers nothing.
274
+ and `stop()`. It can load each known Lyra tag independently, allowing bundlers to split components
275
+ while granular imports remain independent. Importing this entry alone has no side effect and
276
+ registers nothing.
246
277
 
247
278
  - `discover()` scans once. `start()` performs the same initial scan, then observes dynamic and
248
279
  Turbo-style replacement subtrees; a later `start()` stops the previous watcher. `stop()` is
@@ -403,8 +434,8 @@ through `@aceshooting/lyra-ui/events` for listeners on an ancestor, `document` o
403
434
  ## Form association
404
435
 
405
436
  `FormAssociated(Base)` (`@aceshooting/lyra-ui/utilities/form-associated.js`) makes a `LitElement`
406
- form-associated: `static formAssociated = true` plus `attachInternals()` in the constructor, which
407
- eagerly calls
437
+ form-associated: `static formAssociated = true` plus a descriptor-safe `attachInternals` lookup in
438
+ the constructor, which eagerly calls
408
439
  `internals.setFormValue('')` so an untouched control is present in `FormData` as `""` from
409
440
  construction — matching native `<input>` — instead of being absent.
410
441
 
@@ -863,8 +894,8 @@ both modes: `on-<e>` clears WCAG 1.4.3's 4.5:1 against `fill-<e>` at the _same_
863
894
  construction, and no other pairing is promised. `border-normal` and `border-loud` clear 1.4.11's
864
895
  3:1 against the page surface, so a control's visible bounds are always discernible. `border-quiet`
865
896
  is deliberately exempt: it exists for decoration that is not load-bearing — a rule between table
866
- rows, a hairline inside an already-bounded card — so never use it as a control's only boundary. All
867
- of this is checked at build time across both modes, not asserted by hand.
897
+ rows, a hairline inside an already-bounded card — so never use it as a control's only boundary.
898
+ These guarantees apply in both modes.
868
899
 
869
900
  **Every slot has its own `--lr-theme-*` override**, named after the slot, so one decision can be
870
901
  rethemed without forking anything beneath it:
@@ -1092,11 +1123,9 @@ fails when inherited from a wrapper, that is a component bug; setting the same h
1092
1123
  every host should not be necessary.
1093
1124
 
1094
1125
  **There is no way to tell a live `--lr-*` declaration from a dead one without rendering.** A dead
1095
- declaration is byte-identical to a working one in the stylesheet, and nothing in a build reports
1096
- it a test asserting on stylesheet source text (`expect(source).toContain('--lr-token: …')`)
1097
- passes just as happily when the token is being shadowed at a nested host. Verify with
1098
- `getComputedStyle` on the real element in the real state, and perturb the value deliberately to
1099
- confirm the assertion actually bites.
1126
+ declaration is byte-identical to a working one in the stylesheet; a stylesheet-text check cannot
1127
+ distinguish it. Verify with `getComputedStyle` on the real element in the real state, and perturb
1128
+ the value deliberately to confirm the assertion actually bites.
1100
1129
 
1101
1130
  The same trap has a second form inside a component's own styles: a _declared_ value always wins
1102
1131
  over a `var()` fallback arm, and `auto` is a declared value. That is why the exact-height escape
@@ -1722,11 +1751,8 @@ import {
1722
1751
  `CitationSelectEventDetail`, `ToolApprovalEventDetail`, `CancelEventDetail`, `RetryEventDetail`,
1723
1752
  `ExportEventDetail`
1724
1753
 
1725
- The package's no-emit type-test program asserts that each type still matches the property it feeds
1726
- on `lr-chat-message`, `lr-tool-call-chip`, `lr-tool-result-view`, `lr-source-card`,
1727
- `lr-attachment-chip`, and `lr-document-preview`. The binding is enforced by `tsc` without shipping
1728
- an importable contract module. The types are structural and provider-agnostic: map any vendor's
1729
- payload onto them once, at the edge.
1754
+ These structural, provider-agnostic types correspond to the component inputs above; map a vendor
1755
+ payload onto them at the edge.
1730
1756
 
1731
1757
  ### Task-first AI composition guide
1732
1758
 
@@ -1827,24 +1853,17 @@ whose rendering depends on something only a browser can answer — its own light
1827
1853
  browser global such as `EyeDropper` — reproduces the server's answer on the hydrating render and
1828
1854
  corrects itself on the next update, so a slotted override lands one frame after hydration; a
1829
1855
  browser-only mount is unaffected and renders the final result the first time. Layout/observer/canvas/media work
1830
- begins after hydration, and remote content is client-only. CI imports every granular module, renders
1831
- every inventory tag through its declared tier, and crawls a real Chromium DSD page (including
1832
- `lr-page`) while failing hydration warnings/errors or DOM-identity replacement.
1833
-
1834
- ## Testing a downstream project: `@aceshooting/lyra-ui/testing`
1835
-
1836
- `testing/happy-dom-shims.ts` exports `installHappyDomFormAssociatedShims(): void` for a consumer's
1837
- own Vitest + happy-dom suite. happy-dom implements no `ElementInternals`, and every form-associated
1838
- component calls `this.attachInternals()` unconditionally in its constructor, so instantiating one
1839
- throws immediately without the shim. Call it once from a Vitest `setupFiles` entry, before importing
1840
- any component. It patches `HTMLElement.prototype.attachInternals` with a stub covering what the
1841
- components actually call — `setFormValue()`, `setValidity()`, `checkValidity()`, `reportValidity()`,
1842
- plus readonly `form`/`labels`/`validity`/`validationMessage`/`willValidate`. `setValidity()` matters
1843
- beyond construction: `AnchoredValidityController` calls it on every update, so without the shim a
1844
- form control throws on any `value` change, not only when it is created. The shim is a no-op wherever
1845
- `attachInternals` already exists (any real browser), so it is safe to call unconditionally from a
1846
- shared setup file. This package's own tests run in real browsers via `@web/test-runner` and never
1847
- call it.
1856
+ begins after hydration, and remote content is client-only.
1857
+
1858
+ ## Testing form-associated components: `@aceshooting/lyra-ui/testing`
1859
+
1860
+ `@aceshooting/lyra-ui/testing` exports `installHappyDomFormAssociatedShims(): void` for test
1861
+ environments without usable `ElementInternals`. In that environment, form participation is inert
1862
+ while components retain local validity and state behavior. Install the helper once before assertions
1863
+ that need form-value or validity behavior: it supplies
1864
+ `setFormValue()`, `setValidity()`, `checkValidity()`, `reportValidity()`, and readonly
1865
+ `form`/`labels`/`validity`/`validationMessage`/`willValidate`. The shim is a no-op where the
1866
+ platform already provides internals, so it is safe in a shared setup file.
1848
1867
 
1849
1868
  ## Accessibility contract
1850
1869
 
@@ -1870,20 +1889,13 @@ computed name. Check the component's own reference section (or its class JSDoc)
1870
1889
  convention it uses before writing markup — an `accessible-label` attribute on an `aria-label`-only
1871
1890
  component is a silent no-op, not an error.
1872
1891
 
1873
- **What that contract is verified by, precisely.** Every one of the 284 public tags carries at least
1874
- one axe-core assertion in its own directory's tests, in a test that mounts its own tag; contrast
1875
- (4.5:1 text, 3:1 control borders, in both the light and dark palettes), a 40px minimum target size,
1876
- pressed-state coverage for every hoverable part, and `::part()` reachability are separate blocking
1877
- gates. All of that is automated. **No screen reader has been run against this library, in any
1878
- pairing, and no human accessibility audit exists** — so treat "accessible" here as "passes an
1879
- automated rule engine and a written role/name/state contract", never as verified assistive-technology
1880
- behavior, and expect no conformance claim or VPAT. The full statement of what is and is not covered,
1881
- plus how to report an accessibility bug, is at
1892
+ Lyra UI does not make a formal assistive-technology conformance claim or provide a VPAT. For the
1893
+ documented accessibility scope and how to report an accessibility issue, see
1882
1894
  <https://github.com/aceshooting/lyra-ui/blob/main/docs/accessibility.md>.
1883
1895
 
1884
1896
  ## Editor and tooling integration
1885
1897
 
1886
- The published package ships machine-readable metadata for editors, all regenerated on `prepack`:
1898
+ The published package ships machine-readable metadata for editors:
1887
1899
  `custom-elements.json` (Custom Elements Manifest), `web-types.json` (JetBrains, zero-config), and
1888
1900
  `vscode-html-data.json` / `vscode-css-data.json` (point `html.customData` / `css.customData` at them
1889
1901
  in `.vscode/settings.json`). For an agent, `llms/components/<tag>.md` is the cheaper source; these
@@ -2066,7 +2078,9 @@ arrowPadding?: number; hoverBridge?: HTMLElement; onPlaced?: (result: PlacementR
2066
2078
  application can build its **own** form-associated control alongside Lyra's and have it
2067
2079
  participate in a form, restore on reset, and report validity the same way every `lr-` control
2068
2080
  does. Reach for it instead of hand-rolling `attachInternals()` when a bespoke control has to sit
2069
- in the same `<form>` as these.
2081
+ in the same `<form>` as these. `attachInternalsSafely()` inspects own and inherited data
2082
+ descriptors without reading accessors, calls an eligible implementation once, and returns the
2083
+ fallback internals for a missing, accessor-backed, non-callable, or throwing capability.
2070
2084
  The free-function signatures are `attachInternalsSafely(host)`,
2071
2085
  `createStringArrayFormDataState(name, values)`, `readStringArrayFormDataState(state)`, and
2072
2086
  `FormAssociated(Base, valueAdapter?)`. For a non-string value, pass a typed
@@ -2329,13 +2343,10 @@ number; clearTimeout(handle: number): void }`.
2329
2343
  - `formResetCallback()` restores the _content attribute_ default, so `el.value = 'x'` never redefines
2330
2344
  what `form.reset()` restores to (native `defaultValue`/`defaultSelected` semantics).
2331
2345
 
2332
- ## Packaging
2346
+ ## Reference artifacts
2333
2347
 
2334
- `custom-elements.json`, the React/Vue/Svelte declaration entry points, editor metadata, and derived
2335
- LLM artifacts are regenerated by `prepack` and included in `package.json`'s `files` allowlist. The
2336
- family references, this shared guide, and the introductory LLM sources are authored inputs; the
2337
- generated index, per-component pages, tokens, peers, migration reference, and concatenated catalog
2338
- are freshness-checked against them, the manifest, and `dist/` before publication.
2348
+ The package includes authored family and shared references plus derived index, component, token,
2349
+ peer, migration, and concatenated references.
2339
2350
 
2340
2351
  ## When no component fits, file it
2341
2352
 
@@ -5400,6 +5411,10 @@ and `dateTimeFormat(locale, options)`.
5400
5411
  currently-selected paint for a `presets` quick-range button. Defaults are
5401
5412
  `var(--lr-color-brand-quiet)`, that hover colour mixed by `--lr-color-mix-active`, and
5402
5413
  `var(--lr-color-brand)` respectively.
5414
+ - `--lr-date-picker-preset-selected-border` (default `var(--lr-color-brand)`) and
5415
+ `--lr-date-picker-preset-selected-color` (default `var(--lr-color-on-brand)`) independently
5416
+ theme a selected preset's border and foreground; the selected background token controls only its
5417
+ background.
5403
5418
  - `--lr-date-picker-title-hover-color`, `--lr-date-picker-title-active-color`,
5404
5419
  `--lr-date-picker-title-active-bg`, and `--lr-date-picker-title-active-radius` — Month-title
5405
5420
  hover/press paint and pressed shape; defaults to brand, brand, brand-quiet, and
@@ -7782,7 +7797,9 @@ single numeric string entry.
7782
7797
  a range readout joins both values with an en dash. The explicit HTML spelling
7783
7798
  `show-value="false"` stays false.
7784
7799
  - `value: number = 0`, `defaultValue: number = 0` (attribute `value`), `valueAsNumber: number`, and
7785
- `valueAsString: string` are synchronized, finite, clamped, and step-snapped.
7800
+ `valueAsString: string` are synchronized and finite. Values normalize the low/high domain, snap
7801
+ to the grid anchored at the low endpoint, then clamp so a non-grid endpoint remains reachable;
7802
+ invalid, nonpositive, or below-resolution steps are unstepped.
7786
7803
  - `isRange: boolean` is the read-only normalized range-mode state.
7787
7804
  - `name: string | null = null`, `disabled = false`, `required = false`, reflected `customError`,
7788
7805
  plus read-only `form`, `labels`, `validity`, `validationMessage`, and `willValidate` make up the
@@ -8703,6 +8720,8 @@ optional line-number gutter. No syntax highlighting: `language` is metadata only
8703
8720
  emitting an event), and `scrollPosition()` / `scrollPosition({top?,left?})`. The `input` getter
8704
8721
  returns the owned native textarea after render. `selectionStart`, `selectionEnd`, and
8705
8722
  `selectionDirection` use native nullable sentinels before that surface exists.
8723
+ `scrollPosition()` reads or writes `[part="editor"]`'s top/left offsets: the gutter and caret share
8724
+ that single scroll owner rather than a private textarea scroll position.
8706
8725
  The native textarea receives the actual `required` state. Its `aria-invalid` is true whenever
8707
8726
  visible property/slotted error chrome exists, or after interaction while native validity fails;
8708
8727
  showing error chrome alone does not mutate `ElementInternals` validity.
@@ -9351,6 +9370,12 @@ raises `customError` and blocks submission, `''` restores the picker's own compu
9351
9370
  required picker with nothing committed goes back to `valueMissing`. It survives every
9352
9371
  `value`/`required` change and a form reset. `getForm()` returns the browser-resolved owning form.
9353
9372
 
9373
+ The open list is a nonmodal overlay: only its topmost owner handles Escape and outside pointer
9374
+ dismissal; Escape restores the trigger, while Tab keeps ordinary document navigation. Disconnect or
9375
+ cross-document adoption closes it. A required, uncommitted value recomputes its intrinsic localized
9376
+ message when `.strings` or the effective locale changes; an author custom-validity message retains
9377
+ priority until cleared.
9378
+
9354
9379
  **Slots:** `label`, `hint`, `error`.
9355
9380
 
9356
9381
  **CSS parts:** `form-control`, `form-control-label`, `trigger`,
@@ -9412,6 +9437,14 @@ peer warning duplication; `lr-flag` itself already logs one) when the optional
9412
9437
  - `--lr-locale-picker-option-selected-border-color` — Selected option border. Default: `var(--lr-color-brand)`.
9413
9438
  - `--lr-locale-picker-option-selected-color` — Selected option text. Default: `var(--lr-color-brand)`.
9414
9439
 
9440
+ ## Consumer integration notes
9441
+
9442
+ For `lr-input`, `lr-time-input`, and `lr-checkbox-group`, host `aria-describedby` is projected to
9443
+ the semantic native control before built-in hint, error, and required-description ids. Host
9444
+ `aria-labelledby` deliberately does not project: the native label or fieldset legend remains the
9445
+ single name owner. This lets an application add external descriptions without replacing the
9446
+ component's visible form label.
9447
+
9415
9448
  ## Exported TypeScript contracts
9416
9449
 
9417
9450
  These named interfaces and helper signatures are available to typed integrations. They are grouped by capability so the component sections above can stay focused.
@@ -10094,7 +10127,16 @@ body-cell text, `--lr-data-grid-cell-link-color` (default `var(--lr-color-brand)
10094
10127
  anchors, and `--lr-data-grid-cell-link-hover-color` (default
10095
10128
  `var(--lr-data-grid-cell-link-color, var(--lr-color-brand))`) controls those anchors on hover,
10096
10129
  focus-visible, and active interaction. Set the link color to `revert` to restore the user-agent
10097
- default.
10130
+ default. Six independent interaction-background hooks preserve those state boundaries:
10131
+ `--lr-data-grid-control-hover-background` and `--lr-data-grid-control-active-background` theme
10132
+ search, toolbar, pager, and resize controls; `--lr-data-grid-page-size-active-background` themes
10133
+ the page-size selector when pressed; `--lr-data-grid-row-active-background` themes pressed data
10134
+ rows; and `--lr-data-grid-sortable-header-hover-background` and
10135
+ `--lr-data-grid-sortable-header-active-background` theme sortable header states. They default to
10136
+ live `color-mix()` values of the effective grid accent and transparent, using the corresponding
10137
+ `--lr-color-mix-hover` or `--lr-color-mix-active` token (the page-size pressed state intentionally
10138
+ uses the hover mix), so an accent override remains coherent while each surface can still be
10139
+ overridden independently.
10098
10140
 
10099
10141
  ```html
10100
10142
  <lr-data-grid
@@ -12712,9 +12754,11 @@ Responsive month calendar with event markers and an agenda view.
12712
12754
  **Properties:**
12713
12755
 
12714
12756
  - `events: CalendarEvent[] = []` (attribute: false) — `{ readonly id?, readonly date, readonly
12715
- title, readonly color?, readonly data? }`; `date` is an ISO `YYYY-MM-DD` string and `color` is
12716
- sanitized before being used as the marker background. The former ignored `start`/`end` fields
12717
- are not part of the contract; use one event per displayed date
12757
+ title, readonly color?, readonly data? }`; `date` accepts an ISO `YYYY-MM-DD` string, finite epoch
12758
+ milliseconds, or a valid `Date`, then normalizes to the displayed ISO day. Invalid date/title rows
12759
+ are omitted; `lr-event-select.detail.event` remains the original admitted object. `color` is
12760
+ sanitized before use as the marker background. The former ignored `start`/`end` fields are not
12761
+ part of the contract; use one event per displayed date
12718
12762
  - `value: string = ''` — the selected ISO date
12719
12763
  - `viewDate: string` (attribute `view-date`, defaults to the 1st of the current month) — the visible
12720
12764
  month; an unparseable value falls back to the current month
@@ -12756,6 +12800,10 @@ and `--lr-calendar-day-min-block-size-narrow` (default `var(--lr-size-4rem)`, ap
12756
12800
  day's background; `--lr-calendar-day-outside-color` (default `var(--lr-color-text-quiet)`) and
12757
12801
  `--lr-calendar-day-outside-bg` (default `var(--lr-color-surface)`) for adjacent-month days; and
12758
12802
  `--lr-calendar-day-today-outline-color` (default `var(--lr-color-brand)`) for today's outline.
12803
+ `--lr-calendar-nav-hover-bg`, `--lr-calendar-nav-active-bg`, `--lr-calendar-day-hover-bg`,
12804
+ `--lr-calendar-day-active-bg`, `--lr-calendar-agenda-event-hover-bg`, and
12805
+ `--lr-calendar-agenda-event-active-bg` independently theme navigation, day, and agenda-event
12806
+ hover/pressed states through inheritable inline fallbacks.
12759
12807
  These state hooks use inline fallbacks at their paint rules, so an application theme can set them
12760
12808
  on an ancestor. They keep persistent selection, outside-month chrome, and today's outline
12761
12809
  independent from shared tokens that also drive unrelated component states.
@@ -13129,6 +13177,26 @@ At allocations of 320px or less, each condition stacks its composed field/operat
13129
13177
  into one column. Long field labels and localized operator text remain contained and ellipsize inside
13130
13178
  the nested `lr-select` triggers in both LTR and RTL; they do not widen the host or document.
13131
13179
 
13180
+ ## Consumer integration notes
13181
+
13182
+ - **Data grid:** variable-height rows use `[part="body"]` as the only vertical and horizontal scroll
13183
+ viewport; header and footer mirror its logical inline position. Resize `aria-valuenow` stays in
13184
+ CSS pixels while `aria-valuetext` is localized with the effective locale. Row/group measurement is
13185
+ cached by stable identity: after width, columns, locale, or display structure changes, a pending
13186
+ `scrollToIndex()` target realigns after measurement unless a user scroll supersedes the correction.
13187
+ `--lr-data-grid-control-hover-background`, `--lr-data-grid-control-active-background`,
13188
+ `--lr-data-grid-page-size-active-background`, `--lr-data-grid-row-active-background`,
13189
+ `--lr-data-grid-sortable-header-hover-background`, and
13190
+ `--lr-data-grid-sortable-header-active-background` theme those independent state surfaces.
13191
+ - **Table:** resize-handle numeric ARIA ranges remain CSS pixels, with localized current-pixel
13192
+ `aria-valuetext`. Adjacent row-expand controls inherit table typography and use a `1em` glyph.
13193
+ - **Flow canvas:** only direct child cards participate. A matching `node-id` receives the managed
13194
+ `node-{id}` slot. When the canvas stops managing a card, it restores that card's original `slot`
13195
+ only if it has not changed in the meantime; a later author-set `slot` is left intact. Unmatched
13196
+ direct cards do not render because there is no catch-all slot. The first completed connected
13197
+ layout is silent even if truncated; it still shows the limit and emits `lr-layout-change`, while
13198
+ only a later false-to-true truncation transition announces.
13199
+
13132
13200
  ## Exported TypeScript contracts
13133
13201
 
13134
13202
  These named interfaces and helper signatures are available to typed integrations. They are grouped by capability so the component sections above can stay focused.
@@ -13880,7 +13948,7 @@ number; maxPx?: number; minPercent?: number; maxPercent?: number }`, index-align
13880
13948
  renders nothing (`hidden`, out of the accessibility tree) instead of the always-visible overlay
13881
13949
  card this state rendered before `open` existed. Setting `open = true` reveals it as a
13882
13950
  focus-trapped floating panel with a `[part="backdrop"]` scrim; Escape or a backdrop click set
13883
- `open` back to `false`. While open, the floating panel is the modal root and every sibling pane
13951
+ proposes a cancelable close before changing `open`. While open, the floating panel is the modal root and every sibling pane
13884
13952
  behind it is inert. Leaving `'floating'` while `open` is still `true` also closes it, the same
13885
13953
  way `<lr-app-rail>` closes its mobile overlay when leaving `'mobile'` while open.
13886
13954
 
@@ -13903,6 +13971,10 @@ or keyboard step commits. A genuine pointer gesture has one terminal persistence
13903
13971
  release emits no additional event; direct `sizes` assignments stay silent),
13904
13972
  `lr-multi-split-collapse-change` (`detail: { state: 'wide'|'rail'|'floating' }`, fired only
13905
13973
  on a real `collapse`-state transition, never on every resize/render),
13974
+ `lr-toggle` (`detail: LyraMultiSplitToggleDetail = { open: boolean }`) — Escape/backdrop close
13975
+ proposals are cancelable and fire before `open` changes; preventing the event or making a synchronous
13976
+ reentrant mutation aborts the proposal. A forced close when a responsive collapse transition leaves
13977
+ `floating` fires noncancelably after `open` is false. Direct `open` writes and no-op dismissals are silent,
13906
13978
  `lr-multi-split-constraints-invalid` (`detail: LyraMultiSplitConstraintIssueDetail`, fired once when the configured
13907
13979
  panel minimums/maximums cannot fit the track; the infeasible set is rejected for interaction and a
13908
13980
  normalized percent minimum is used instead), `lr-multi-split-orientation-change` (`detail: { orientation }`,
@@ -14526,11 +14598,11 @@ well as full-width layouts.
14526
14598
  - `scrollStep: number = 0` (attribute `scroll-step`) — custom step; zero uses 80% of the viewport
14527
14599
  - `label: string = ''` — accessible region name; a host `aria-label` is used when set
14528
14600
 
14529
- **Events:** `lr-scroll` with `scrollStart`, `scrollEnd`, `scrollLeft`, and `scrollTop` in the
14530
- detail object. Scroll-driven emissions are coalesced through one `requestAnimationFrame` tick, so a
14531
- fling that fires dozens of native `scroll` events produces at most one `lr-scroll` per frame the
14532
- same contract `lr-virtual-list`'s identically-named event carries, so the two are interchangeable
14533
- for scroll-linked layout work.
14601
+ **Events:** `lr-scroll` has detail `{ scrollStart, scrollEnd, scrollLeft, scrollTop }`.
14602
+ Scroll-driven emissions are coalesced through one `requestAnimationFrame` tick, so a fling that
14603
+ fires dozens of native `scroll` events produces at most one `lr-scroll` per frame. This is the
14604
+ scroller's own event shape, not `lr-virtual-list`'s `lr-virtual-scroll` event
14605
+ (`{ scrollTop, viewportHeight }`).
14534
14606
 
14535
14607
  **Slots:** default scrollable content.
14536
14608
 
@@ -16751,16 +16823,17 @@ from assistive technology: do not place independent links, buttons, inputs, form
16751
16823
  targets there. The accordion-item `icon` slot follows the same flattened-tree inert and aria-hidden
16752
16824
  visual contract, while the trigger button remains the sole action. Details has `summary`,
16753
16825
  `header-actions`, `expand-icon`, `collapse-icon`, plus default content. `header-actions` renders
16754
- extra controls (e.g. a trailing "add" button) inside the `<summary>` header row the one subtree a
16755
- native `<details>` keeps out of its generated content box — so they stay rendered, visible, and
16756
- hit-testable while the panel is collapsed. Activating one never toggles the panel: a click whose
16826
+ extra controls (e.g. a trailing "add" button) as a sibling of the private native `<details>` in the
16827
+ complete header row, so they stay rendered, visible, and hit-testable while the panel is collapsed
16828
+ or disabled. Activating one never toggles the panel: a click whose
16757
16829
  composed path crosses `[part~="header-actions"]` is exempted from disclosure activation. Its wrapper
16758
16830
  is hidden and reclaims layout space whenever the slot is empty.
16759
16831
 
16760
16832
  **CSS parts:** accordion exposes `base`. Accordion item exposes `base` and `accordion-item` on the
16761
16833
  same outer wrapper, plus `heading`, `button`, `label`, `icon`, `panel`, and `content`. Details
16762
- exposes `base` and `details` on the same native `<details>` wrapper, plus `header`, `summary`,
16763
- `icon`, `header-actions`, and `content`.
16834
+ exposes `base` and `details` on the same outer container, plus `header`, `summary`, `icon`,
16835
+ `header-actions`, and `content`. The native `<details>` is private; `content` is inside its
16836
+ findable `hidden="until-found"` closed-state gate.
16764
16837
  The Details icon wrapper also carries Shoelace's `summary-icon` alias, so either part name styles
16765
16838
  the same node. `header-actions` is the wrapper around the `header-actions` slot.
16766
16839
 
@@ -17396,6 +17469,22 @@ import "@aceshooting/lyra-ui/components/layout/page/page.js";
17396
17469
  </lr-page>
17397
17470
  ```
17398
17471
 
17472
+ ## Consumer integration notes
17473
+
17474
+ - **Multi-split:** `LyraMultiSplitToggleDetail` is `{ open: boolean }`. Escape or a backdrop click
17475
+ proposes a floating-panel state cancelably before `open` changes; `preventDefault()` or a
17476
+ synchronous reentrant write aborts the proposal. Leaving floating mode closes the panel, emits
17477
+ the collapse change, and then emits noncancelable `lr-toggle`; direct writes and no-ops stay
17478
+ silent. Divider numeric ARIA values remain percentages and their `aria-valuetext` is localized.
17479
+ - **Resizers:** `lr-split-panel` retains numeric percent ranges with localized current-percent
17480
+ `aria-valuetext`; `lr-app-rail` and `lr-dock-panel` expose CSS-pixel ranges with localized current
17481
+ width/extent text. The app-rail toggle inherits rail typography and its glyph is `1em`.
17482
+ - **Details structure:** `base` is the outer details container and `header` is its complete row.
17483
+ A private native `<details>` owns the summary; `header-actions` is its sibling after that native
17484
+ element, stays enabled and non-toggling even while the disclosure is disabled, and `content` is
17485
+ behind a private `hidden="until-found"` gate. `beforematch` or a fragment reveal follows the
17486
+ normal programmatic lifecycle, or re-arms the gate after a veto or disabled state.
17487
+
17399
17488
  ## Exported TypeScript contracts
17400
17489
 
17401
17490
  These named interfaces and helper signatures are available to typed integrations. They are grouped by capability so the component sections above can stay focused.
@@ -17691,6 +17780,9 @@ These named interfaces and helper signatures are available to typed integrations
17691
17780
  - **`components-layout-multi-split-multi-split-contracts`** — Supporting data types and helpers for this component family.
17692
17781
  `LyraMultiSplitCollapseChangeDetail {
17693
17782
  state: unknown;
17783
+ }`
17784
+ `LyraMultiSplitToggleDetail {
17785
+ readonly open: boolean;
17694
17786
  }`
17695
17787
  `LyraMultiSplitConstraintIssueDetail {
17696
17788
  reason: unknown;
@@ -20195,6 +20287,11 @@ associated external label focuses the host-owned slider without changing its val
20195
20287
  property is visible label text, since a rating is a bare row of symbols with no field frame of its
20196
20288
  own; wrap the element in your own layout for a labelled field, exactly as `<lr-slider>` does.
20197
20289
 
20290
+ For the managed slider name only, an empty or whitespace-only `label` counts as absent and falls
20291
+ through to localized `rating`; the raw `label` property still reads exactly as assigned. An
20292
+ associated external label and an authored `aria-label`, including `aria-label=""`, keep their
20293
+ existing precedence and are never replaced by that fallback.
20294
+
20198
20295
  **Static constructor API:** `LyraRating.validators` is the mirrored callable validator catalog.
20199
20296
  Each access returns a fresh `LyraFormValidator<LyraRating>[]`; its entry observes
20200
20297
  `required`/`disabled`/`readonly`/`value`/`max`, and `checkValidity(element)` projects the element's
@@ -20525,6 +20622,15 @@ downloadBlob(content: string, filename: string, mime: string, ownerDocument?: Do
20525
20622
 
20526
20623
  **Known gotchas:**
20527
20624
 
20625
+ - Format options are read from their direct data fields into a frozen list. Accessor-backed, missing,
20626
+ malformed, or throwing descriptor fields are ignored rather than evaluated; later menu rendering
20627
+ and `lr-export` events use that snapshot. The snapshot includes only direct `formatId`, `label`,
20628
+ `description`, and `extension` fields; accepted records are frozen and never reread from the
20629
+ caller. An open multi-format menu is a non-modal overlay owned by the element's
20630
+ current document: only its topmost menu handles that document's Escape, outside pointer, or Tab.
20631
+ It rebinds after document adoption; Escape or a selected export returns focus to its own trigger,
20632
+ while a Tab close permits normal document navigation. Placement uses the current trigger and panel
20633
+ geometry and remains clamped to the current document's viewport.
20528
20634
  - CSV and JSON are the only built-in encoders. To offer XLSX/PDF/etc., pass an
20529
20635
  `LyraExportFormatDescriptor` and handle its `formatId` from `lr-export`; custom formats never trigger a
20530
20636
  download or `lr-export-complete` on their own. A descriptor's optional `extension` is metadata
@@ -20591,7 +20697,10 @@ positioning opinion of its own.
20591
20697
  **Methods:** `focus(options?)`, `blur()` and `click()` forward to the active built-in or custom
20592
20698
  trigger. `getToolbarActions(): readonly LyraToolbarAction[]` implements the public logical-toolbar
20593
20699
  provider protocol with one stable action whose id is `copy`; its focus, roving tab index, disabled
20594
- state, and composed-event matching follow the active trigger without exposing that node.
20700
+ state, and composed-event matching follow the active trigger without exposing that node. Its
20701
+ `releaseTabIndex()` action method lets a parent stop managing its tab index on disconnect, adoption,
20702
+ trigger replacement, and parent departure: an untouched author-supplied `tabindex` is restored,
20703
+ while a newer author change is never overwritten.
20595
20704
 
20596
20705
  **Events:**
20597
20706
 
@@ -20745,6 +20854,15 @@ boolean = false` (reflected; unobserves a target after its first intersection).
20745
20854
  target stays consumed across option-driven observer rebuilds and disconnect/reconnect cycles;
20746
20855
  setting `once` to false is the explicit reset boundary.
20747
20856
 
20857
+ The browser capability is optional. A missing or throwing owner-window lookup or unavailable
20858
+ constructor leaves that rebuild inert rather than leaking an exception; an initial construction
20859
+ failure retries once with safe default options. Individual `observe`, `unobserve`, and `disconnect`
20860
+ failures are contained, so later valid targets and later rebuilds can still observe. Callbacks are
20861
+ tied to the current owner document, so a detached or adopted wrapper cannot emit a stale batch.
20862
+ Threshold collections inspect at most their first 10,000 direct data entries. Malformed or
20863
+ accessor-backed entries are skipped; a valid prefix remains active, while an entirely unusable value
20864
+ falls back to threshold `0`.
20865
+
20748
20866
  **Events:** mapped `lr-intersect` once per entry with `{ entry }`, plus the existing batch alias
20749
20867
  `lr-intersection` with a frozen
20750
20868
  `Readonly<{ entries: readonly IntersectionObserverEntry[] }>` detail. The batch sequence is
@@ -20771,6 +20889,14 @@ form of `attr`, equivalent to `attr: '*'`) and `characterData` (`character-data`
20771
20889
  `charData`). Plus `subtree: boolean = true`, and programmatic `attributeFilter: string[] = []`
20772
20890
  (neither reflects).
20773
20891
 
20892
+ The browser capability is optional. A missing or throwing owner-window lookup, or an unavailable or
20893
+ throwing constructor, leaves that rebuild inert rather than leaking an exception. Individual
20894
+ `observe` and `disconnect` failures are contained, so later valid targets and later rebuilds can still observe.
20895
+ Callbacks from a retired document are ignored after disconnect or adoption. `attributeFilter` is
20896
+ likewise a bounded own-data snapshot (examining at most its first 10,000 direct data entries);
20897
+ malformed or accessor-backed entries are skipped, a valid prefix remains active, and an entirely
20898
+ unusable value falls back to an empty filter.
20899
+
20774
20900
  **Events:** `lr-mutation`; its detail and bounded readonly record sequence are frozen.
20775
20901
  `detail.records` and mapped `detail.mutationList` reference the same sequence, while each native
20776
20902
  `MutationRecord` retains identity.
@@ -20783,7 +20909,12 @@ form of `attr`, equivalent to `attr: '*'`) and `characterData` (`character-data`
20783
20909
 
20784
20910
  A collapsible, copyable tree view for an arbitrary JSON-serializable value (object, array, string,
20785
20911
  number, boolean, null, or `undefined`). Serves as a fallback renderer wherever a raw payload needs
20786
- inspecting without a bespoke view. Expand/collapse state is keyed by structural path (not object
20912
+ inspecting without a bespoke view. Assignment creates one bounded, frozen graph from own enumerable
20913
+ data descriptors. It never invokes getters or object-conversion hooks; accessor/reflection-failed
20914
+ branches and function or symbol leaves are omitted, while bigint is retained as decimal text.
20915
+ Rendering, searching, toolbar copy, and per-node copy all use that same owned graph, so later
20916
+ mutation or revocation of the supplied object cannot change a displayed or copied value. Ordinary
20917
+ aliases, cycles, and sparse-array holes are retained. Expand/collapse state is keyed by structural path (not object
20787
20918
  identity), so it survives a `data` reassignment that keeps the same shape — e.g. a streaming result
20788
20919
  being patched in place. A container value that self-references (directly or through a longer cycle)
20789
20920
  renders as a leaf `Circular reference` marker (`data-type="circular"`) instead of recursing — no
@@ -21156,13 +21287,14 @@ called. Phase transitions ("Paused.", "Resumed.", "Refreshing now.") are announc
21156
21287
 
21157
21288
  A caret-anchored, keyboard-navigable popover for `@`-mention and `/`-slash-command autocomplete
21158
21289
  inside a plain-text `<textarea>`/`<input>` the host owns. First-party invention (no Web Awesome
21159
- equivalent). While open with a text-control `anchor`, the component atomically projects
21160
- `role="combobox"` (unless the author supplied a role), `aria-expanded`, `aria-haspopup`, a
21161
- resolvable controls element, and the active descendant. On platforms accepting cross-root ARIA
21162
- element reflection, the host's own input keeps focus. Where the active-option reference is
21163
- rejected, `focusActiveOption()` moves real focus into this component's shadow listbox so the focus
21164
- owner and option share one tree scope. Every author ARIA value is restored on close, anchor
21165
- replacement, disconnect, or adoption; a cross-root string IDREF is never left behind.
21290
+ equivalent). A textarea keeps its native textbox semantics while open and, after a consumed
21291
+ navigation key, `focusActiveOption()` moves real focus to the active option in the shadow listbox.
21292
+ A single-line text input retains its active-descendant element-reference route; only that route
21293
+ uses `syncActiveDescendant()`, which returns `false` for a textarea.
21294
+ Textarea ARIA/AOM values are restored on close, anchor replacement, disconnect, or adoption; a
21295
+ cross-root string IDREF is never left behind. Later localized result-count and active-position
21296
+ changes are announced once through the shared polite region; opening markup and unchanged state are
21297
+ silent.
21166
21298
 
21167
21299
  **Properties:**
21168
21300
 
@@ -21204,9 +21336,10 @@ replacement, disconnect, or adoption; a cross-root string IDREF is never left be
21204
21336
  `preventDefault()` when `filteredItems` is empty, letting the keystroke fall through to the
21205
21337
  host's own control unchanged. `Escape` closes with no selection. Returns `true` whenever the key
21206
21338
  was intercepted and `false` for keys the method does not recognize.
21207
- - `syncActiveDescendant(control: HTMLElement): boolean` — clears any string
21208
- `aria-activedescendant`, then applies `ariaActiveDescendantElement` when the platform accepts the
21209
- cross-root reference. Returns whether that reference was accepted.
21339
+ - `syncActiveDescendant(control: HTMLElement): boolean` — applies
21340
+ `ariaActiveDescendantElement` only for a retained single-line input route. For a textarea it
21341
+ returns `false` without mutating `aria-activedescendant`; the managed textarea session clears that
21342
+ value separately.
21210
21343
  - `focusActiveOption(options?: LyraMentionFocusOptions): Promise<boolean>` — same-tree fallback
21211
21344
  after a consumed navigation key when `syncActiveDescendant()` returns `false`. Focuses the active
21212
21345
  option, lets the popover handle subsequent navigation, and restores focus to `anchor` when the
@@ -21390,6 +21523,12 @@ First-party invention (no Web Awesome equivalent).
21390
21523
  highlighting the diff. `Infinity` relaxes this line-count ceiling, but the fixed aggregate
21391
21524
  character and comparison-work ceilings remain in force.
21392
21525
 
21526
+ Grammar entries are read from own enumerable data fields into a bounded frozen map. A getter,
21527
+ unreadable field, non-enumerable field, or malformed proxy branch is skipped without preventing a
21528
+ later valid grammar from being used; grammar values themselves remain opaque to the component.
21529
+ Non-enumerable names do not consume language slots, but every inspected name counts toward the
21530
+ 20,000 structural ceiling.
21531
+
21393
21532
  **Events:**
21394
21533
 
21395
21534
  - `lr-copy` (`detail: LyraClipboardWriteSuccess`, `{ ok: true; text: string }`) — the frozen full
@@ -21770,7 +21909,9 @@ granular fields are then ignored entirely (`Intl` throws when the two are mixed)
21770
21909
  to use the granular set. An unparseable `date` renders the default slot. An invalid
21771
21910
  `timeZone` throws a `RangeError` inside `Intl`, which is caught and retried once without the zone —
21772
21911
  so the output falls back to the browser's local zone instead of failing to render. Valid output is
21773
- wrapped in semantic `<time datetime="…">`.
21912
+ wrapped in semantic `<time datetime="…">`. Date input accepts primitive strings/numbers or a
21913
+ genuine `Date`; arbitrary objects are rejected without calling their `valueOf()`, `toString()`, or
21914
+ other conversion hooks.
21774
21915
 
21775
21916
  **Slots:** default — fallback content for an invalid/unparseable `date`.
21776
21917
 
@@ -21820,6 +21961,8 @@ are as described under `lr-format-number` above.
21820
21961
 
21821
21962
  Valid output is semantic `<time datetime="…">`. **Slots:** none — an unparseable `date` renders the
21822
21963
  empty string, with no fallback-content hook (unlike the three `lr-format-*` components above).
21964
+ Date input accepts primitive strings/numbers or a genuine `Date`; arbitrary objects are rejected
21965
+ without calling their conversion hooks.
21823
21966
 
21824
21967
  ## `lr-known-date`
21825
21968
 
@@ -22683,8 +22826,7 @@ dimming at `itemCount <= 1`), `--lr-focus-ring-*`.
22683
22826
  `currentIndex` clamped into `[0, itemCount)`; fractional, negative, `NaN`, infinite, and oversized
22684
22827
  values cannot poison end conditions or the slider.
22685
22828
  - `interval-ms` is clamped to the 16ms floor and the browser's finite timer ceiling: a non-finite or
22686
- lower value ticks at 16ms, while an oversized value uses the timer ceiling. Each distinct invalid
22687
- value is warned once (deduplicated per value, not a single once-ever flag).
22829
+ lower value ticks at 16ms, while an oversized value uses the timer ceiling.
22688
22830
  - Initial `playing` and `item-count` attributes are resolved together on the first update, so
22689
22831
  playback starts consistently regardless of their source order; an invalid final `itemCount <= 1`
22690
22832
  clears the reflected `playing` state.
@@ -22776,7 +22918,8 @@ string; geojson: GeoJSON.FeatureCollection; field: string; stops: [number, strin
22776
22918
  the live host cascade before passing the expression to MapLibre's WebGL renderer.
22777
22919
  - `markers: LyraMapMarker[] = []` (attribute: false) — `LyraMapMarker { id?: string; lngLat:
22778
22920
  [number, number]; color?: string; label?: string; unsafeHtml?: string }`; an explicit `id` is
22779
- trimmed and must be nonempty, and the first marker for an explicit ID wins. Markers are reconciled
22921
+ trimmed and must be nonempty, and the first successfully admitted marker for an explicit ID wins.
22922
+ A malformed earlier row does not reserve that ID. Markers are reconciled
22780
22923
  by that explicit ID (falling back
22781
22924
  to a `lng,lat` key, disambiguated by occurrence order for duplicate-coordinate id-less markers,
22782
22925
  when `id` is omitted) so an unchanged marker isn't torn down and recreated on every `markers`
@@ -22802,7 +22945,8 @@ string; geojson: GeoJSON.FeatureCollection; field: string; stops: [number, strin
22802
22945
  GeoJSON.FeatureCollection; tone?: 'accent' | 'success' | 'warning' |
22803
22946
  'danger' | 'neutral'; color?: string; strokeColor?: string; kind?: LyraMapDataLayerKind;
22804
22947
  heatmap?: LyraMapHeatmapOptions; cluster?: LyraMapClusterOptions }`. `sourceId` is trimmed and must be nonempty; the first layer for a
22805
- `sourceId` wins and blank or later duplicate records are ignored. Each retained entry adds one
22948
+ `sourceId` that is successfully admitted wins; blank, malformed, and later duplicate records are
22949
+ ignored without reserving an identity for a valid later sibling. Each retained entry adds one
22806
22950
  GeoJSON source plus three geometry-filtered layers
22807
22951
  (fill, line, and circle, so a mixed `FeatureCollection` renders correctly), colored from the
22808
22952
  matching `--lr-color-*` token (`tone` defaults to `'accent'` → `--lr-color-brand`).
@@ -22826,6 +22970,10 @@ heatmap?: LyraMapHeatmapOptions; cluster?: LyraMapClusterOptions }`. `sourceId`
22826
22970
  its private source/layers removed, and a genuinely new `sourceId` gets new resources — nothing
22827
22971
  leaks on removal, style change, or disconnect.
22828
22972
 
22973
+ The component snapshots the configuration it reads. It passes `choropleth.geojson` and
22974
+ `dataLayers[].geojson` through to MapLibre; assign a new `choropleth`, `dataLayers`, or `markers`
22975
+ value after changing configuration, because mutating an assigned value is not observed.
22976
+
22829
22977
  `cluster` and `kind` (both new in 12.0.0) opt one entry out of that three-layer geometry split.
22830
22978
  **Both are strictly additive: an entry that sets neither renders exactly what it rendered before,
22831
22979
  down to the layer ids and the point layer's filter.**
@@ -22898,9 +23046,9 @@ expensive on an animated one. When every feature has a unique `string`/`number`
22898
23046
  features keep semantically unchanged geometry/bbox values, the component emits MapLibre's
22899
23047
  incremental `updateData()` for property changes, additions, removals, and order changes. The exact
22900
23048
  next order is preserved: an unchanged prefix stays in place and only the invalidated suffix is
22901
- removed and re-added. Lyra's immutable ownership boundary detaches GeoJSON assignments, so geometry
22902
- reference identity cannot survive between frames; a bounded, accessor-free comparison verifies the
22903
- JSON geometry graph instead. A missing/duplicate ID, changed geometry, exceeded bound, or uncertain
23049
+ removed and re-added. Lyra snapshots control and projection data while retaining opaque GeoJSON
23050
+ identity at the MapLibre boundary; a bounded, accessor-free comparison verifies the JSON geometry
23051
+ graph instead. A missing/duplicate ID, changed geometry, exceeded bound, or uncertain
22904
23052
  comparison falls back to `setData()` with no change in rendered behaviour. Peers without
22905
23053
  `updateData()` always take the old path.
22906
23054
 
@@ -22955,6 +23103,10 @@ zoom-to-cluster handler reads. The count label is deliberately not hit-tested (i
22955
23103
  the circle already queried and would only make the label the topmost hit), and a `kind: 'heatmap'`
22956
23104
  layer is never queried at all — MapLibre returns no features for a rendered density surface
22957
23105
 
23106
+ The outer marker-activation detail is frozen, while an opaque marker `unsafeHtml` value remains the
23107
+ original supplied value at the MapLibre popup and marker-activation boundary. Treat it as trusted
23108
+ markup as described above.
23109
+
22958
23110
  **Slots:** `legend` — custom legend content, rendered inside the legend panel's own layout so it
22959
23111
  stays positioned with the map instead of floating beside it. Supplying it opens the panel even
22960
23112
  when `legend` and `legendGradient` are both empty.
@@ -23188,10 +23340,8 @@ no client-side CSV/XLSX/etc. parsing is performed (that's left entirely to the h
23188
23340
  `resetValidity()`; reset clears only consumer custom validity and restores current intrinsic
23189
23341
  `required` validity.
23190
23342
 
23191
- **Events:** a user selection or removal emits native bubbling/composed `input`, then `change`;
23192
- programmatic `files` writes are silent. The hidden native picker's own `change` is contained inside
23193
- the shadow root, so a picker selection exposes exactly one post-commit host `change`, not the
23194
- implementation event plus a duplicate. `lr-files` (`detail: LyraFileInputFilesDetail`, with fresh
23343
+ **Events:** a user selection or removal emits native bubbling/composed `input`, then exactly one
23344
+ host `change`; programmatic `files` writes are silent. `lr-files` (`detail: LyraFileInputFilesDetail`, with fresh
23195
23345
  frozen readonly `files` and `rejected` arrays and frozen rejected-file records, fired on both drop
23196
23346
  and manual file-picker selection; immutable `File` objects retain identity) —
23197
23347
  `LyraFileInputRejectedFile = { readonly file: File; readonly reason: 'type' | 'count' | 'size' | 'directory' | 'read' | 'limit'
@@ -23252,10 +23402,9 @@ What this changes for you:
23252
23402
  - **Nothing about what the visible text says or where it renders.** `[part="rejection"]`'s text is
23253
23403
  ordinary visible content and stays in the accessibility tree, so a user who reaches it reads it
23254
23404
  normally. Both parts remain the right styling hooks.
23255
- - **A test that asserted `::part(rejection)` had `role="alert"`, or that read announcements out of
23256
- `::part(status)`, now fails.** Assert against the shared light-DOM region instead — query
23257
- `[data-lr-live-region="assertive"]` (or `"polite"`) in the document, which is also where every
23258
- other Lyra announcement lands.
23405
+ - **Read announcements from the shared light-DOM region** query
23406
+ `[data-lr-live-region="assertive"]` or `[data-lr-live-region="polite"]` in the document rather
23407
+ than the styling parts.
23259
23408
  - **A `::part(rejection)[role]`-style selector never matched anyway** — an attribute selector
23260
23409
  cannot follow `::part()`. Nothing that worked before stopped working.
23261
23410
 
@@ -23670,9 +23819,8 @@ already focused on the chip still hears an upload failure — goes to the librar
23670
23819
  can read at their own pace, and a retry that fails the same way twice is announced twice rather
23671
23820
  than being a silent no-op. The ticking `uploading` readout announces nothing at all — a live
23672
23821
  region re-announcing every progress tick is noise, not information.
23673
- - A test that asserted `::part(status-text)` had `role="alert"` now fails; query
23674
- `[data-lr-live-region="assertive"]` in the document instead. `::part(status-text)` is still the
23675
- styling hook, and still the place to read the visible status wording.
23822
+ - Read the announcement from `[data-lr-live-region="assertive"]` in the document;
23823
+ `::part(status-text)` remains the styling hook and visible-status text.
23676
23824
 
23677
23825
  **Themeable custom properties:** `--lr-attachment-chip-accent` (default
23678
23826
  `var(--lr-color-text-quiet)`), `--lr-attachment-chip-bg` (default `var(--lr-color-surface)`),
@@ -23931,12 +24079,6 @@ the video's own native controls bubble up and spuriously fire `lr-media-open`.
23931
24079
 
23932
24080
  **Known gotchas:**
23933
24081
 
23934
- - Calling the real `.click()` (or dispatching a `click`/`MouseEvent`) on the file-chip's `<a href>`
23935
- in a test genuinely triggers real browser navigation — always `preventDefault()` on a `click`
23936
- listener registered before triggering it, the same precaution `lr-document-preview`'s own
23937
- download-link tests already take. A synthetic `dispatchEvent(new MouseEvent('click', {cancelable:
23938
- true}))` still invokes the anchor's native activation behavior if nothing calls
23939
- `preventDefault()` during dispatch — it is not a safe no-op.
23940
24082
  - `kind` only reflects to the host attribute when explicitly set — CSS keying off the
23941
24083
  auto-detected resolved kind should target the rendered `[part]`/element (e.g. `video[part="media"]`),
23942
24084
  not `:host([kind=...])`, since the latter won't see an auto-detected kind.
@@ -24515,6 +24657,12 @@ generation-guarded, including across disconnect/reconnect.
24515
24657
  `LyraQrCode.preload(): Promise<boolean>` is a static optional-peer warm-up that starts the shared
24516
24658
  `qrcode` import without encoding a value; it resolves to `false` when the peer is unavailable.
24517
24659
 
24660
+ When `IntersectionObserver` is available, painting waits for a valid intersecting entry and resumes
24661
+ whenever the code re-enters view. If the API is unavailable, its constructor fails, or `observe()`
24662
+ throws, rendering proceeds immediately. Invalid resolved paint colors fall back to the documented
24663
+ safe fill/background without changing the QR's loading or error state: foreground becomes black,
24664
+ background becomes transparent, and `imageBackground` becomes the resolved QR background.
24665
+
24518
24666
  At ordinary sizes the backing store is a fixed `2×` the CSS size, independent of device pixel
24519
24667
  ratio. It degrades uniformly only to stay within 4,096 pixels per dimension and 8,388,608 total
24520
24668
  pixels. Modules span the full canvas with no injected quiet zone; add host padding when a scanner
@@ -25504,7 +25652,10 @@ property).
25504
25652
  - `formatter?: LyraChartFormatter` (attribute: false) — the family-wide context-object formatter:
25505
25653
  `({ value, surface, datasetIndex?, index?, label?, seriesLabel?, statistic? }) => string`.
25506
25654
  `surface` identifies `visual`, `spoken`, `export`, `tick`, `tooltip`, `legend`, or `table`.
25507
- It takes precedence over the legacy positional `valueFormatter` where both are supplied.
25655
+ `statistic`, when present for a structured datum or stack total, is one of `x`, `y`, `r`,
25656
+ `min`, `q1`, `median`, `q3`, `max`, or `total`. It takes precedence over the legacy positional
25657
+ `valueFormatter` where both are supplied. The legacy callback remains a visual/table compatibility
25658
+ hook; use `formatter` when a generated spoken value or CSV cell must use the same unit text.
25508
25659
  - `area: boolean = false` — chart-wide default for whether line-type series fill the region under
25509
25660
  their line; a series's own `fill` overrides it, rendered with a translucent version of its color
25510
25661
  - `zoom: boolean = false` — wheel/drag/pinch zoom on the `x` axis only (pan disabled, and the zoom
@@ -25559,8 +25710,10 @@ property).
25559
25710
  consumers wrapping a duplicated table in their own `<details>`. With the toggle on,
25560
25711
  `showDataTable` becomes the disclosure's **initial** state rather than its whole behavior; the
25561
25712
  table stays in the DOM in both states, so assistive technology never loses it, and the button
25562
- carries `aria-expanded` plus `aria-controls` pointing at the `data-table` wrapper. Unset, nothing
25563
- renders and behavior is identical to before.
25713
+ carries `aria-expanded` plus `aria-controls` pointing at the `data-table` wrapper. Until the
25714
+ reader activates it, the disclosure follows `showDataTable`; afterwards the reader's selected
25715
+ state remains authoritative for that mounted chart. A supplied `slot="data-table"` follows this
25716
+ same disclosure state. Unset, nothing renders and behavior is identical to before.
25564
25717
  - `chartArea: LyraChartArea | undefined` (readonly) — current Chart.js chart-area geometry in
25565
25718
  canvas-local coordinates (`top`, `left`, `right`, `bottom`, `width`, `height`), when a chart is
25566
25719
  drawn
@@ -25715,7 +25868,8 @@ plot in narrow containers;
25715
25868
  declaration on a DOM element (the outline is painted by the stylesheet, not by Chart.js), so it is
25716
25869
  consumed directly with no `getComputedStyle` bridging; it is an inline `var()` fallback at the point
25717
25870
  of use, so it can be set on the element or any ancestor, and left unset the outline is exactly the
25718
- `--lr-border-width-thin` it always was.
25871
+ `--lr-border-width-thin` it always was. `--lr-chart-canvas-hover-outline-color` (default
25872
+ `var(--lr-chart-grid-color)`) independently controls that outline's color.
25719
25873
 
25720
25874
  `--lr-chart-pattern-step` (default `var(--lr-space-2xs)`) is the tile size of the texture painted on
25721
25875
  `[part="legend-swatch"]` while `forced-colors: active` matches — the legend half of the non-colour
@@ -25891,7 +26045,8 @@ passthrough). Not a subclass of `LyraChart`.
25891
26045
  more here than on `lr-chart`: this component exists to avoid the Chart.js peers, so without it an
25892
26046
  app that chose it for exactly that reason had to either hand-roll a `<details>` around a
25893
26047
  duplicated table or adopt `lr-chart` and pull in Chart.js for a button — the cheap component
25894
- stuck with the expensive workaround. Unset, nothing renders and behavior is unchanged.
26048
+ stuck with the expensive workaround. A supplied `slot="data-table"` follows the same disclosure
26049
+ state. Unset, nothing renders and behavior is unchanged.
25895
26050
  Themeable via `--lr-lite-chart-data-table-toggle-hover-bg` (default
25896
26051
  `var(--lr-color-brand-quiet)`) and `--lr-lite-chart-data-table-toggle-active-bg` (default: that
25897
26052
  hover colour mixed by `--lr-color-mix-active`).
@@ -25967,10 +26122,12 @@ passthrough). Not a subclass of `LyraChart`.
25967
26122
  equivalent for the full charts.
25968
26123
  - `withoutValueAxis: boolean = false` (attribute `without-value-axis`) — suppresses gridlines and
25969
26124
  value-axis tick labels; x-axis category labels remain.
25970
- - `selectedIndices: readonly number[] = []` (attribute: false) — applies to every interactive data mark for
25971
- both `type="bar"` and `type="line"`: matching bars and line points receive `data-selected` and
25972
- explicit `aria-pressed="true"`; all other marks render `aria-pressed="false"`. For a multi-series
25973
- chart, the category index selects the matching mark in every dataset. Empty is the default.
26125
+ - `selectedIndices: readonly number[] = []` (attribute: false) — names **source category indices**,
26126
+ not positions in the sampled SVG output. Finite integer entries whose source rows are represented
26127
+ in the bounded rendered sample select matching bars and line points, which receive
26128
+ `data-selected` and explicit `aria-pressed="true"`; all other marks render `aria-pressed="false"`.
26129
+ For a multi-series chart, a selected source category selects the matching rendered mark in every
26130
+ dataset. Empty is the default.
25974
26131
  Style the built-in highlight through `--lr-lite-chart-selected-outline-color` and
25975
26132
  `--lr-lite-chart-selected-outline-width`. Note
25976
26133
  `::part(bar)[data-selected]` and `::part(point)[data-selected]` are **invalid CSS** — Shadow Parts
@@ -26144,7 +26301,7 @@ failure transition is announced through the shared document-level light-DOM asse
26144
26301
  `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
26145
26302
  `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
26146
26303
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
26147
- `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — all inherited from `LyraChart`, identical in meaning and default (see
26304
+ `--lr-chart-canvas-hover-outline-color`, `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — all inherited from `LyraChart`, identical in meaning and default (see
26148
26305
  `lr-chart` above); each of the eight variants below reads the same set, so one rule retunes them
26149
26306
  together. The mirrored hooks are `--border-color-1`,
26150
26307
  `--border-color-2`, `--border-color-3`, `--border-color-4`, `--border-color-5`,
@@ -26228,7 +26385,7 @@ inherited from `LyraChart`, unaffected by the binning logic).
26228
26385
  `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
26229
26386
  `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
26230
26387
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
26231
- `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — inherited from `LyraChart`, identical in meaning, together with the
26388
+ `--lr-chart-canvas-hover-outline-color`, `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — inherited from `LyraChart`, identical in meaning, together with the
26232
26389
  mirrored `--border-color-1`,
26233
26390
  `--border-color-2`,
26234
26391
  `--border-color-3`, `--border-color-4`, `--border-color-5`, `--border-color-6`, `--fill-color-1`,
@@ -26299,8 +26456,9 @@ browser). Does **not** extend `LyraChart` — a deliberately bespoke API.
26299
26456
  - `formatter?: LyraChartFormatter`, `valueFormatter?: LyraChartValueFormatter` — numeric axis,
26300
26457
  tooltip, table, summary, and export formatting. The context-object formatter receives the
26301
26458
  family-wide `spoken` surface for the generated summary and `export` for CSV cells; the legacy
26302
- positional formatter continues to receive `table` for both compatibility paths. The
26303
- context-object formatter takes precedence
26459
+ positional formatter receives `table` for the spoken/export compatibility paths, its normal
26460
+ surface name for axis, tooltip, and table work, and no fallback for a `visual` context. The
26461
+ context-object formatter takes precedence.
26304
26462
  - `showDataTable: boolean = false` (attribute `show-data-table`) — reveals the accessible data table
26305
26463
  - `dataTableToggle: boolean = false` (attribute `data-table-toggle`, new in 11.0.0) — renders a
26306
26464
  localized disclosure button (`part="data-table-toggle"`) above the data table so a *sighted*
@@ -26308,8 +26466,9 @@ browser). Does **not** extend `LyraChart` — a deliberately bespoke API.
26308
26466
  consumers wrapping a duplicated table in their own `<details>`. With the toggle on,
26309
26467
  `showDataTable` becomes the disclosure's **initial** state rather than its whole behavior; the
26310
26468
  table stays in the DOM in both states, so assistive technology never loses it, and the button
26311
- carries `aria-expanded` plus `aria-controls` pointing at the `data-table` wrapper. Unset, nothing
26312
- renders and behavior is identical to before.
26469
+ carries `aria-expanded` plus `aria-controls` pointing at the `data-table` wrapper. A supplied
26470
+ `slot="data-table"` follows this same disclosure state. Unset, nothing renders and behavior is
26471
+ identical to before.
26313
26472
 
26314
26473
  **Methods:** `exportData('csv'|'png')` returns spreadsheet-safe summary rows or the current canvas
26315
26474
  PNG data URL. `refreshTheme()` re-reads canvas theme custom properties after an ancestor theme
@@ -26363,7 +26522,8 @@ that sets no `color` is assigned an entry from the same `--lr-color-chart-1..8`
26363
26522
  so `--lr-theme-color-chart-*` retheming reaches box plots too. `--lr-chart-pattern-step`
26364
26523
  (default `var(--lr-space-2xs)`) sizes the forced-colors legend texture and
26365
26524
  `--lr-chart-canvas-hover-outline-width` (default `var(--lr-border-width-thin)`) sizes the `canvas`
26366
- hover outline, `--lr-chart-legend-item-active-bg` and `--lr-chart-legend-item-hover-bg` retune the
26525
+ hover outline; `--lr-chart-canvas-hover-outline-color` (default `var(--lr-chart-grid-color)`) sets
26526
+ its color. `--lr-chart-legend-item-active-bg` and `--lr-chart-legend-item-hover-bg` retune the
26367
26527
  pressed and hovered legend rows, and `--lr-chart-legend-side-max` caps a side legend — the same tokens and defaults as
26368
26528
  `lr-chart`. Its own `dataTableToggle` disclosure button carries box-plot-namespaced hooks rather
26369
26529
  than inheriting the chart pair, since its stylesheet is not a re-export:
@@ -26421,8 +26581,10 @@ These helpers do not download files; compose them with
26421
26581
  `lr-export-button` so the host owns filenames and download policy.
26422
26582
 
26423
26583
  For route-level warming, the side-effect-free chart preload entry exports
26424
- `preloadCharts({ zoom?, dataLabels?, boxPlot? })`. Core Chart.js is always requested and optional
26425
- capabilities only when flagged; the result reports which requested capabilities are available.
26584
+ `preloadCharts({ zoom?, dataLabels?, annotations?, boxPlot? })`. Core Chart.js is always requested
26585
+ and optional capabilities only when flagged; the result reports which requested capabilities are
26586
+ available. `annotations` appears in the result only when requested, and is `true` only after the
26587
+ optional annotation peer loads.
26426
26588
 
26427
26589
  ## Exported TypeScript contracts
26428
26590
 
@@ -26514,12 +26676,14 @@ These named interfaces and helper signatures are available to typed integrations
26514
26676
  `LyraChartPreloadOptions {
26515
26677
  zoom: unknown;
26516
26678
  dataLabels: unknown;
26679
+ annotations: unknown;
26517
26680
  boxPlot: unknown;
26518
26681
  }`
26519
26682
  `LyraChartPreloadResult {
26520
26683
  core: unknown;
26521
26684
  zoom: unknown;
26522
26685
  dataLabels: unknown;
26686
+ annotations: unknown;
26523
26687
  boxPlot: unknown;
26524
26688
  }`
26525
26689
  `preloadCharts(/* public names: options */): unknown`
@@ -26730,7 +26894,11 @@ image path — and the generic fallback simply omits `[part="download-link"]` en
26730
26894
  - `highlights: readonly LyraHighlight[] = []` (attribute: false) — display-only `region` highlights painted
26731
26895
  over the image-format preview; ignored for the `text`/`generic` formats. IDs are trimmed and
26732
26896
  required to be nonempty, with the first record retained when IDs repeat. A rectangle renders only
26733
- when `x`/`y`/`width`/`height` are finite numbers and both dimensions are nonnegative.
26897
+ when `x`/`y`/`width`/`height` are finite numbers and both dimensions are nonnegative. Image-region
26898
+ geometry is captured when `highlights` is assigned: an invalid or accessor-backed `region` anchor
26899
+ is ignored, and mutating an accepted anchor later does not move its painted region. Reassign
26900
+ `highlights` to update it; the original public anchor identity remains available for
26901
+ reference-based `scrollToAnchor()`.
26734
26902
  - `activeHighlightId: string | null = null` (attribute `active-highlight-id`) — the `highlights`
26735
26903
  entry, if any, currently treated as active (`data-active` on its `region-highlight`).
26736
26904
  - `anchorKinds: readonly LyraAnchor['kind'][] = ['region']` (this viewer's supported
@@ -26792,7 +26960,11 @@ every other element that read them. The tone-specific resting border and hover t
26792
26960
  `--lr-document-preview-highlight-accent-color`, `--lr-document-preview-highlight-success-color`,
26793
26961
  `--lr-document-preview-highlight-warning-color`, `--lr-document-preview-highlight-danger-color`,
26794
26962
  and `--lr-document-preview-highlight-neutral-color` (defaulting respectively to the matching
26795
- brand/success/warning/danger/neutral color tokens). Plus shared tokens
26963
+ brand/success/warning/danger/neutral color tokens). `--lr-document-preview-download-link-hover-bg`
26964
+ defaults to `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner)
26965
+ var(--lr-color-mix-hover))`; `--lr-document-preview-download-link-active-bg` uses the same mix with
26966
+ `var(--lr-color-mix-active)`, styling the native download action's hover and pressed backgrounds.
26967
+ Plus shared tokens
26796
26968
  `--lr-color-border`, `--lr-radius`, `--lr-color-surface`, `--lr-space-s/-m/-l/-xs`,
26797
26969
  `--lr-color-text`, `--lr-color-text-quiet`, `--lr-color-danger`, `--lr-color-brand`,
26798
26970
  `--lr-color-on-brand`, `--lr-focus-ring-width/-color/-offset`, `--lr-transition-fast`.
@@ -26932,6 +27104,10 @@ polite and assertive sinks, respectively;
26932
27104
 
26933
27105
  **Themeable custom properties:** `--lr-document-viewer-max-height` (default `70vh`) — maximum block
26934
27106
  size of `[part="body"]` before the dialog body scrolls internally.
27107
+ `--lr-document-viewer-download-link-hover-bg` defaults to `color-mix(in oklab,
27108
+ var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`, and
27109
+ `--lr-document-viewer-download-link-active-bg` uses `var(--lr-color-mix-active)` in that same mix
27110
+ for the native download action's hover and pressed backgrounds.
26935
27111
 
26936
27112
  **Renderer registry exports:**
26937
27113
 
@@ -27083,6 +27259,12 @@ resolved keyboard action was activated.
27083
27259
  content. `lr-anchor-result` (`detail: { found }`) — fired after an `anchor` assignment or a
27084
27260
  `scrollToAnchor()` call.
27085
27261
 
27262
+ Mammoth's conversion result is usable only when it has own-data `value: string` and an own-data
27263
+ `messages` array; an unusable primary result is terminal. From a usable result, the first 100
27264
+ message positions are considered, malformed entries are omitted, and valid opaque causes are
27265
+ retained in their diagnostics. Sanitized document content remains visible while those non-fatal
27266
+ diagnostics are emitted.
27267
+
27086
27268
  **CSS parts:** `base`, `body`, `content`, `spinner`, `error`, `highlight` (a painted `text-quote`
27087
27269
  highlight), `highlight-actions` (keyboard-accessible actions for resolved highlights),
27088
27270
  `highlight-action` (one native highlight activation button), `search-match` (a painted in-document
@@ -27140,6 +27322,11 @@ An attachment with no filename uses the localized `emailViewerUnnamedAttachment`
27140
27322
  `lr-attachment-open` detail. The fallback resolves while rendering, so changing the locale or
27141
27323
  per-instance `strings` after the message loads updates it without reparsing the message.
27142
27324
 
27325
+ Parser output is admitted through a bounded direct-data projection: malformed optional fields,
27326
+ recipients, and attachment entries are omitted without discarding later valid siblings. Accepted
27327
+ string, `Uint8Array`, and `ArrayBuffer` attachment bytes are copied before use, and every
27328
+ `lr-attachment-open` creates a fresh Blob, so later source mutation cannot change event bytes.
27329
+
27143
27330
  Sanitized HTML uses the passive-document profile: anchors, form controls, and custom elements are
27144
27331
  unwrapped to ordinary text/children where safe, remote navigation/resource attributes are removed,
27145
27332
  and an `<a>` itself never remains. Images render only inline base64 GIF, JPEG, PNG, or WebP data;
@@ -27337,7 +27524,9 @@ Remote resources are capped at 25 MB; exceeding it surfaces the localized
27337
27524
 
27338
27525
  Renders EPUB ebooks through the optional `epubjs` peer. `src` is fetched as an `ArrayBuffer`, and
27339
27526
  epub.js renders the reading area into its stable `mount` element, using an internal iframe for
27340
- chapter content.
27527
+ chapter content. A usable book exposes `ready`, `renderTo()`, and `destroy()`, and its rendition
27528
+ exposes `display()`, `prev()`, `next()`, `on()`, and `annotations.highlight()`/`remove()`; an absent
27529
+ required capability is terminal. Navigation and spine data are optional.
27341
27530
 
27342
27531
  **Properties:** `src: string = ''` and `name: string = ''`. A plain `aria-label` attribute on the
27343
27532
  host overrides the reading region's accessible name — by attribute presence, so an explicitly empty
@@ -27358,14 +27547,17 @@ viewer's supported `LyraAnchor.kind` values for the shared anchor-target contrac
27358
27547
  **Methods:** `getToc()` resolves the EPUB's own navigation document (`book.navigation.toc`,
27359
27548
  populated once `book.ready` resolves) flattened into document-ordered `EbookTocItem[]` (`{ id,
27360
27549
  label, href, level }`, `level` starting at 1 for a top-level entry, `id` falling back to `href`
27361
- when a navigation entry has none), `[]` before a book has loaded. `search(query)` resolves the
27550
+ when a navigation entry has none), `[]` before a book has loaded or when navigation is absent. TOC
27551
+ projection examines at most 10,000 positions, nodes, and depth 100; malformed entries are skipped
27552
+ without preventing later valid entries. `search(query)` resolves the
27362
27553
  match count across every spine section, in document order, via epub.js's own `item.load()`/
27363
27554
  `item.find()`/`item.unload()` (empty/whitespace query behaves like `clearSearch()`; a newer
27364
27555
  `search()` call or a `src` change aborts an in-flight scan; peer output is capped at 10,000
27365
27556
  matches after at most 1,000 spine items and 4,000,000 result code units; queries are capped at 4,096
27366
27557
  code units); `searchNext()`/`searchPrevious()`
27367
27558
  advance/step back through matches (wrapping, resolving `false` when there are none); `clearSearch()`
27368
- clears the query, matches, and painted search annotation.
27559
+ clears the query, matches, and painted search annotation. `matchCountExact: false` also reports
27560
+ malformed or holey spine/find data and failed section load/unload work, not only a search ceiling.
27369
27561
 
27370
27562
  **Events:** `lr-render-error` with `detail.error` when fetching, opening, or rendering fails;
27371
27563
  `lr-location-change` (`detail: { cfi, href }`) fired from epub.js's own `relocated` event;
@@ -28583,7 +28775,10 @@ is absent, it uses the localized comparison label. Dynamic host-label changes up
28583
28775
  - `oldVersion?: DocumentCompareVersion`, `newVersion?: DocumentCompareVersion` (attribute: false) —
28584
28776
  the before/after inputs. `DocumentCompareVersion` extends `DocumentRef`
28585
28777
  (`id`, `name`, `mimeType?`, `uri?`, `version?`) with `text?: string` for diff mode and
28586
- `highlights?: LyraHighlight[]` for its own preview pane.
28778
+ `highlights?: LyraHighlight[]` for its own preview pane. Each assignment becomes a frozen
28779
+ snapshot: own string `id` and `name` are required or that pane is unset; valid string optional
28780
+ fields are retained and other values are omitted. Its highlights use the shared snapshot too, so
28781
+ mutation requires reassignment.
28587
28782
  - `view: 'diff' | 'side-by-side' = 'diff'` (reflected) — one inline text diff or two rendered
28588
28783
  preview panes. Invalid property or attribute values normalize to `diff` and repair the reflected
28589
28784
  attribute.
@@ -28592,7 +28787,8 @@ is absent, it uses the localized comparison label. Dynamic host-label changes up
28592
28787
  repair the reflected attribute.
28593
28788
  - `copyable: boolean = false` — forwards the diff copy action.
28594
28789
  - `language: string = ''`, `languages?: Record<string, ShikiLanguageInput>` (the latter
28595
- attribute: false) — optional syntax highlighting forwarded to the diff.
28790
+ attribute: false) — optional syntax highlighting forwarded to the diff. A runtime non-string
28791
+ `language` is treated as `''` without coercion.
28596
28792
  - `syncScroll: boolean = true` (attribute `sync-scroll`) — proportionally mirrors either
28597
28793
  side-by-side pane's scroll fraction to the other. The true-default converter accepts the literal
28598
28794
  `sync-scroll="false"`.
@@ -29241,7 +29437,9 @@ uses for its own `[part="body"]`.
29241
29437
  to plain text if the peer is unavailable; `escape` displays raw HTML source as text while ordinary
29242
29438
  Markdown still renders; `trusted` renders raw HTML without sanitization and is only for trusted
29243
29439
  content.
29244
- - `gfm: boolean = true` — GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists)
29440
+ - `gfm: boolean = true` — GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists).
29441
+ GFM task-list checkboxes stay disabled. A task's primary inline text supplies its accessible name;
29442
+ nested task text is excluded, and a blank task receives no generated name.
29245
29443
  - `linkTarget: string | null = '_blank'` (attribute `link-target`) — `target` applied to every
29246
29444
  rendered `<a>`, with `rel="noopener noreferrer"` always added alongside it whenever a `target` is
29247
29445
  emitted. `'_blank'` (the default) preserves the original output; a falsy value (`null`, or the
@@ -29307,9 +29505,10 @@ placed first and preserved inside both ceilings.
29307
29505
 
29308
29506
  **Events:**
29309
29507
 
29310
- - `lr-link-click` (`detail: { href: string }`) — fired, with the click prevented,
29311
- when a rendered link's `href` starts with `internal-link-prefix`; ordinary external links navigate
29312
- normally and never fire this
29508
+ - `lr-link-click` (`detail: { href: string }`) — fired, with navigation prevented, when a rendered
29509
+ link's `href` starts with `internal-link-prefix`; ordinary external links navigate normally and
29510
+ never fire this. If an intercepted link overlaps a painted highlight,
29511
+ `lr-highlight-activate` fires first for pointer and Enter activation.
29313
29512
  - `lr-render-error` (`detail: { error: unknown }`) — rendering fell back to plain text (see the
29314
29513
  fallback matrix below), or `math` is set but the `katex` peer isn't installed
29315
29514
  - `lr-highlight-activate` (`detail: { highlightId: string }`) — a painted `text-quote` highlight was clicked
@@ -29811,7 +30010,8 @@ reveals the invalid state, and `form.reset()` clears the touched presentation.
29811
30010
  - `minRows: number = 1` (attribute `min-rows`) — floored to `1` at render time
29812
30011
  - `maxRows: number = 8` (attribute `max-rows`) — floored to at least `minRows`
29813
30012
  - `status: ChatComposerStatus = 'idle'` (reflected) — `'idle' | 'sending' | 'streaming'`; drives the
29814
- built-in button's icon/label (send vs. stop) and whether Enter still submits
30013
+ built-in button's icon/label (send vs. stop) and whether Enter still submits. Invalid direct or
30014
+ attribute values normalize and reflect as `idle`.
29815
30015
  - `frame: ChatComposerFrame = 'card'` (reflected) — container treatment, in the library-wide `frame`
29816
30016
  vocabulary (`'card' | 'plain'`; `ChatComposerFrame` is an alias of the shared `LyraFrame`).
29817
30017
  `'plain'` drops `[part="base"]`'s border, background, padding and corner radius so a composer
@@ -30299,6 +30499,9 @@ focus move.
30299
30499
  they have no effect in closed-dropdown mode
30300
30500
  - `name: string = ''` (reflected)
30301
30501
  - `disabled: boolean = false` (reflected)
30502
+ - `readonly: boolean = false` (reflected) — prevents user typing and catalog
30503
+ commits while retaining focus, popup navigation, selection/copy, submission/reset, and programmatic
30504
+ writes.
30302
30505
  - `required: boolean = false` (reflected — enforced via `internals.setValidity()`)
30303
30506
  - `open: boolean = false` (reflected)
30304
30507
  - `size: LyraSize = 'm'` (reflected) — visual size on the library-wide ladder: `2xs`/`xs`/`s`/`m`/
@@ -30398,8 +30601,8 @@ every labelled control in the library uses, so `--lr-form-control-required-conte
30398
30601
  `--lr-form-control-required-color` and `--lr-form-control-required-offset` retune or suppress it here
30399
30602
  exactly as they do on `lr-input` (see `llms/shared.md` → "The required-field marker"). With no visible label there
30400
30603
  is nothing to mark and no stray glyph is rendered. Correspondingly, while the picker is barred from
30401
- constraint validation — its own `disabled`, or an ancestor `<fieldset disabled>`; this control has no
30402
- `readonly` — it reports no violation and publishes neither `:state(invalid)` nor
30604
+ constraint validation — its own `disabled` or `readonly`, or an ancestor `<fieldset disabled>` it
30605
+ reports no violation and publishes neither `:state(invalid)` nor
30403
30606
  `:state(user-invalid)`, matching native `:invalid`. `required`/`optional` keep publishing.
30404
30607
 
30405
30608
  **CSS parts:** `form-control` (the complete label, control, hint, error, and listbox frame),
@@ -30545,9 +30748,8 @@ property and therefore never requests `katex` itself.
30545
30748
  ```
30546
30749
 
30547
30750
  Token-by-token streaming can update `content` far faster than a human can usefully perceive a
30548
- re-render, so updates funnel through `Announcer` (`../../internal/announcer.js`), reused here
30549
- purely as a generic "coalesce rapid calls, flush the latest" timing primitive — with none of that
30550
- class's usual DOM/ARIA plumbing. Within any `coalesce-ms` window, only the _last_ `content` value
30751
+ re-render, so updates use a shared coalescing timer. Within any `coalesce-ms` window, only the
30752
+ _last_ `content` value
30551
30753
  assigned actually reaches the rendered DOM. Two cases always bypass the throttle and flush
30552
30754
  immediately: the very first `content` assignment after mount, and any transition of `streaming`
30553
30755
  between `true` and `false` in _either_ direction — so the final chunk of a finished stream can
@@ -30690,8 +30892,8 @@ something that announces state _transitions_ instead. The Stop button gets a nor
30690
30892
  ## `lr-code-block`
30691
30893
 
30692
30894
  Fenced code display with optional lazy syntax highlighting and a copy button. First-party invention
30693
- (no Web Awesome equivalent). It lazy-loads the optional peer dependency `shiki` (see
30694
- `code-loader.ts`) for the actual tokenizing, and includes a compact GreyCat/GCL grammar because
30895
+ (no Web Awesome equivalent). It lazily loads the optional `shiki` peer for syntax highlighting and
30896
+ includes a compact GreyCat/GCL grammar because
30695
30897
  Shiki does not bundle one. It falls back to a plain `<pre><code>` when that peer isn't installed or
30696
30898
  `language` is unset/unrecognized. That
30697
30899
  fallback is the _default_ rendering path, not a degraded one: unhighlighted code is perfectly usable,
@@ -30722,7 +30924,8 @@ and it's what every instance renders at zero extra bytes until shiki resolves.
30722
30924
  numbers for both highlighted output and the plain-text fallback
30723
30925
  - `highlightLines: string = ''` (attribute `highlight-lines`) — comma-separated 1-based inclusive
30724
30926
  line ranges (e.g. `"3-5,7"`) to visually emphasize. Declarative sugar over `highlights` — merges
30725
- with, and renders identically to, any `line-range` entries there.
30927
+ with, and renders identically to, any `line-range` entries there. Malformed segments are ignored
30928
+ while valid segments still apply.
30726
30929
  - `activatableLines: boolean = false` (attribute `activatable-lines`) — turns the
30727
30930
  (`lineNumbers`-gated) gutter into a roving-tabindex group of buttons emitting `lr-line-activate`.
30728
30931
  Has no effect while `lineNumbers` is unset. If controlled `code` shrinks while a line owns
@@ -30801,14 +31004,10 @@ so it inherits: set it on the element, on an ancestor, or at the theme level.
30801
31004
  `:host` declaration) so it inherits, retinting just the highlighted-line background and leaving every
30802
31005
  other `--lr-color-warning-quiet` surface alone.
30803
31006
 
30804
- **Optional peer deps:** `shiki` (lazy-loaded and cached once per page by `code-loader.ts`'s
30805
- `loadShikiHighlighter()`, which builds a single `Highlighter` seeded with the bundled `github-light`/
30806
- `github-dark` "dual themes" and _zero_ language grammars up front; each `language` a
30807
- `<lr-code-block>` actually requests is loaded incrementally on first use via
30808
- `loadShikiLanguage()`, and a language id that fails to load once is remembered and never retried. If
30809
- `shiki` isn't installed, `loadShikiHighlighter()` resolves to `null` with a one-time `console.warn`
30810
- and every instance falls back to plain text — install it with `pnpm add shiki` to enable
30811
- highlighting).
31007
+ **Optional peer deps:** `shiki` requested only when syntax highlighting is used and shared by
31008
+ code blocks on a page. Languages load on demand. If the peer or requested language is unavailable,
31009
+ every instance retains a readable plain-text fallback; install it with `pnpm add shiki` to enable
31010
+ highlighting.
30812
31011
 
30813
31012
  ```ts
30814
31013
  import { html } from "lit";
@@ -30847,9 +31046,8 @@ one deliberate exception to every other color being a `--lr-*` token.
30847
31046
 
30848
31047
  - `copyable` defaults to `true` and reflects — literal `copyable="false"` and a `.copyable=${false}`
30849
31048
  property binding both disable it; a `?copyable=${false}` boolean-attribute binding does not.
30850
- - an in-flight per-language grammar load is guarded by an internal token so a `code`/`language` change
30851
- that arrives before a previous load resolves never applies a stale result — only the load matching
30852
- the _current_ `language` is ever rendered.
31049
+ - if `code` or `language` changes while highlighting is loading, only the result matching the
31050
+ current values is rendered.
30853
31051
  - a malformed `code`/`language` combination that makes shiki's `codeToHtml()` throw falls back to
30854
31052
  plain text silently, not a blank code block.
30855
31053
  - the "Copied!" label appears only after clipboard fulfillment and reverts to "Copy" after 1500ms.
@@ -30901,7 +31099,8 @@ toggle, the loading-skeleton behavior while the fine-grained highlighter resolve
30901
31099
  numbers for highlighted and plain output.
30902
31100
  - `highlightLines: string = ''` (attribute `highlight-lines`) — comma-separated 1-based inclusive
30903
31101
  line ranges (e.g. `"3-5,7"`) to visually emphasize. Declarative sugar over `highlights` — merges
30904
- with, and renders identically to, any `line-range` entries there.
31102
+ with, and renders identically to, any `line-range` entries there. Malformed segments are ignored
31103
+ while valid segments still apply.
30905
31104
  - `activatableLines: boolean = false` (attribute `activatable-lines`) — turns the
30906
31105
  (`lineNumbers`-gated) gutter into a roving-tabindex group of buttons emitting `lr-line-activate`.
30907
31106
  Has no effect while `lineNumbers` is unset. If controlled `code` shrinks while a line owns
@@ -30915,8 +31114,8 @@ toggle, the loading-skeleton behavior while the fine-grained highlighter resolve
30915
31114
  - `languages: Record<string, ShikiLanguageInput> = {}` (attribute: false) — grammar definitions this
30916
31115
  instance can highlight, e.g. `{ json: jsonGrammar }` (import from `shiki/langs/<name>.mjs`). Empty
30917
31116
  (the default) never highlights at all — every `language` renders the plain-text fallback.
30918
- Replacing the map while connected starts a new loading generation; an older map that settles
30919
- later cannot clear the current map's loading state or replace its highlighted output. For a
31117
+ If `languages` changes while highlighting is loading, only results for the current map can update
31118
+ the displayed code. For a
30920
31119
  TypeScript annotation, use `import type { ShikiLanguageInput } from
30921
31120
  '@aceshooting/lyra-ui/components/conversation/code-block/code-block-core.js'`; the type-only
30922
31121
  granular import emits no registration side effect.
@@ -30925,7 +31124,6 @@ toggle, the loading-skeleton behavior while the fine-grained highlighter resolve
30925
31124
  resolving to one) by scrolling its start line into view within `[part="body"]`; resolves `false`
30926
31125
  when the anchor isn't a `line-range`, the id isn't found, or the start line is out of bounds.
30927
31126
  `refreshTheme(): void` re-reads the resolved theme for syntax highlighting.
30928
- `refreshTheme(): void` re-reads the resolved theme for syntax highlighting.
30929
31127
  Identical behavior to `<lr-code-block>`'s own method.
30930
31128
 
30931
31129
  **Events:** the same fulfilled-only `lr-copy`, generic `lr-error`, full `lr-copy-error`, cancelable
@@ -31088,10 +31286,11 @@ wired to a WebAudio `AnalyserNode`; `level: number | null = null` — a pre-comp
31088
31286
  hosts that already have one (e.g. `lr-push-to-talk`'s `lr-level` detail); `state: 'idle' |
31089
31287
  'listening' | 'thinking' | 'speaking' = 'idle'` (reflected) — drives the signal-less ambient
31090
31288
  animation and per-state coloring; `mode: AudioVisualizerMode = 'bars'` (`'bars' | 'waveform'`,
31091
- reflected); `barCount: number = 5` (attribute `bar-count`); `gain: number = 1` multiplier applied
31092
- to the resolved amplitude; `label: string =
31093
- ''` — accessible-name override. Invalid `state` or `mode` attribute/property writes normalize to
31094
- `idle` and `bars` respectively.
31289
+ reflected); `barCount: number = 5` (attribute `bar-count`, normalized to an integer in `[1, 64]`);
31290
+ `gain: number = 1` — multiplier applied to the resolved amplitude, with a non-finite value treated
31291
+ as `1`; `label: string = ''` — accessible-name override. `level` is clamped to `[0, 1]`; after gain,
31292
+ waveform and bar values are clamped to `[-1, 1]` and `[0, 1]` respectively. Invalid `state` or
31293
+ `mode` attribute/property writes normalize to `idle` and `bars` respectively.
31095
31294
 
31096
31295
  **Methods:** `refreshTheme()` re-reads themeable custom properties after a runtime theme change (the
31097
31296
  canvas resolves token values at paint time and cannot inherit `var()` directly). Canvas-bound
@@ -31104,8 +31303,10 @@ or empty `MediaStream` tears down the prior analyser transaction immediately and
31104
31303
 
31105
31304
  **Slots:** none.
31106
31305
 
31107
- **CSS parts:** `base` (the root wrapper) and `canvas` (the drawing surface, `aria-hidden`; the host
31108
- itself carries `role="img"` and the accessible name).
31306
+ **CSS parts:** `base` (the root wrapper) and `canvas` (the drawing surface, `aria-hidden`). The host
31307
+ supplies `role="img"` only while an author has not supplied a role; an authored role is preserved,
31308
+ and removing it restores `img`. If observation cannot be established, it draws eagerly; otherwise
31309
+ it waits for a valid observer entry and pauses offscreen.
31109
31310
 
31110
31311
  **Themeable custom properties:** `--lr-audio-visualizer-color` (default `var(--lr-color-brand)` —
31111
31312
  active bar/waveform color), `--lr-audio-visualizer-quiet-color` (default
@@ -31167,19 +31368,26 @@ intent events, so each built-in can occur at most once. `copyText: string = ''`
31167
31368
  (attribute `copy-text`) — required for the `copy` built-in to render at all. `feedbackRating:
31168
31369
  MessageFeedbackValue = null` (attribute `feedback-rating`) — forwarded to the embedded, thumbs-only
31169
31370
  `lr-message-feedback` (its `detail`/`detailFor` are never forwarded, so its detail panel never
31170
- opens). `revealOnInteraction: boolean = false` (reflected, attribute `reveal-on-interaction`) — hides
31371
+ opens). `feedbackPending: boolean` (read-only, nonreflecting) — true only while the current built-in
31372
+ feedback control awaits settlement; it has no `feedback-pending` attribute or change event.
31373
+ `revealOnInteraction: boolean = false` (reflected, attribute `reveal-on-interaction`) — hides
31171
31374
  the bar until the closest `lr-chat-message` ancestor is hovered, or the toolbar contains focus.
31172
31375
  `label: string = ''` — accessible name override for the toolbar. `accessibleLabel: string | null =
31173
31376
  null` (attribute `aria-label`) — overrides the toolbar's computed accessible name, winning over
31174
31377
  `label` and the localized default; attribute-reflects from a host-level `aria-label`.
31175
31378
 
31379
+ **Methods:** `finalizePendingSubmit(submissionId: string): boolean` and
31380
+ `revertPendingSubmit(submissionId: string): boolean` settle only the current built-in feedback
31381
+ request. Both return `false` for blank, stale, mismatched, removed, or replaced requests.
31382
+
31176
31383
  **Events:** `lr-regenerate`/`lr-edit` — a built-in was activated, `detail: null`. `lr-copy` —
31177
31384
  frozen `detail: { ok: true, text }`, emitted only after the embedded `lr-copy-button`'s clipboard
31178
31385
  write fulfills (bubbles/composed already, not re-emitted). A failed write surfaces generic
31179
31386
  `lr-error` (`detail: null`) plus `lr-copy-error` with frozen
31180
31387
  `detail: { ok: false, text, reason, error }`; `reason` is `'unsupported' | 'denied' | 'failed'`.
31181
- `lr-feedback-change`/`lr-feedback-submit` — bubble unchanged from the embedded,
31182
- thumbs-only `lr-message-feedback`. A colliding event from an
31388
+ `lr-feedback-change`/`lr-feedback-submit` — bubble unchanged from the embedded, thumbs-only
31389
+ `lr-message-feedback`; the frozen submit detail includes its `submissionId`, which is the value to
31390
+ pass to either settlement method. A colliding event from an
31183
31391
  arbitrary slotted child is contained at that slot boundary rather than being mistaken for a
31184
31392
  built-in action.
31185
31393
 
@@ -31216,21 +31424,34 @@ owns that one detail panel. `disabled: boolean = false` (reflected) makes a reco
31216
31424
  submission while host persistence is unresolved; all feedback controls are disabled and the panel
31217
31425
  reports busy until that state is resolved.
31218
31426
 
31427
+ When the optional comment textarea renders, `spellcheck: boolean = true`,
31428
+ `autocapitalize: string = ''`, `autocorrect: boolean = true`, and
31429
+ `wrap: MessageFeedbackWrap = 'soft'` forward to it; they have no effect without that textarea.
31430
+ `MessageFeedbackWrap` is `'soft' | 'hard' | 'off'`, the native textarea wrap vocabulary.
31431
+
31219
31432
  **Methods:** `focus()` focuses the thumb matching the current `rating` (the up thumb when `null`);
31220
31433
  `blur()` blurs both thumbs; `click()` activates that same thumb when enabled.
31221
31434
  `getToolbarActions()` returns the ordered logical thumb actions used by an enclosing toolbar.
31222
- `finalizePendingSubmit()` completes a prevented submit after persistence succeeds, closing the
31223
- panel, announcing success, and returning focus to the active thumb. `revertPendingSubmit()` releases
31224
- the pending state after failure without clearing the draft or announcing success, leaving the panel
31225
- open for retry. Both are no-ops when no submit is pending.
31435
+ `finalizePendingSubmit(submissionId?: string): boolean` completes a prevented submit after persistence succeeds, closing the
31436
+ panel, announcing success, and returning focus to the active thumb.
31437
+ `revertPendingSubmit(submissionId?: string): boolean` releases
31438
+ the pending state after failure without clearing the draft or announcing success, restoring the
31439
+ prior rating and panel state. A detail-panel submit remains open for retry, while a thumbs-only
31440
+ submit remains panel-free; it likewise accepts an optional `submissionId` and returns `boolean`. The event
31441
+ supplies a nonblank, never-reused id; a later/current settlement must use that exact id. Legacy
31442
+ no-argument settlement remains available only for the first transaction that has never been
31443
+ invalidated; stale or mismatched settlements return `false`.
31226
31444
 
31227
31445
  **Events:** `lr-feedback-change` — `detail: { rating: 'up' | 'down' | null }`, fired when a thumb's
31228
31446
  provisional rating changes or clears. `lr-feedback-submit` — cancelable
31229
- `detail: { rating: 'up' | 'down' | null; reasonIds: string[]; comment: string }`, fired for every
31447
+ `detail: { rating: 'up' | 'down' | null; reasonIds: string[]; comment: string; submissionId: string }`, fired for every
31230
31448
  terminal thumbs-only choice/clear and by the detail panel's submit button. The pending transaction
31231
- is installed before dispatch, so even a synchronous listener may finalize/revert it safely.
31449
+ is installed before dispatch, so even a synchronous listener may finalize/revert it safely. The
31450
+ event detail is frozen.
31232
31451
  `preventDefault()` holds the panel/control in `pending` and delays
31233
- success announcement/focus until `finalizePendingSubmit()`; call `revertPendingSubmit()` on failure.
31452
+ success announcement/focus until `finalizePendingSubmit(detail.submissionId)`; call
31453
+ `revertPendingSubmit(detail.submissionId)` on failure. The no-argument form is only the documented
31454
+ legacy first-transaction path.
31234
31455
  When uncanceled it retains the synchronous close/announce/focus behavior. The optional comment
31235
31456
  `<textarea>`'s native `focus` and `blur` are re-dispatched as bubbling, composed host events.
31236
31457
  `lr-toolbar-actions-change` is the no-detail coordination event emitted when the provider's logical
@@ -31292,6 +31513,11 @@ setting it to `0` removes the deadline.
31292
31513
  **Methods:** `start()`, `stop()`, and `cancel()` drive the capture lifecycle imperatively (mirroring
31293
31514
  the pointer/keyboard gestures).
31294
31515
 
31516
+ After permission is requested, only a still-active control in the same document may begin
31517
+ recording; otherwise any stream returned later is immediately stopped. In hold mode, a later held
31518
+ press in that document can take over one pending permission request, and a held press while
31519
+ stopping begins after the prior take ends. Only one capture runs at a time.
31520
+
31295
31521
  **Slots:** `microphone-icon` replaces the default mic glyph. `recording-icon` replaces the default
31296
31522
  recording-state pulse glyph. Both are
31297
31523
  decorative inside the named trigger: their flattened content is inert and hidden from accessibility
@@ -31580,6 +31806,10 @@ Data-mode thread ids must be nonempty, nonblank, and unique, and every row must
31580
31806
  before the mode is selected, so focus, actions, slot ownership, and emitted `conversationId`
31581
31807
  values remain unambiguous.
31582
31808
 
31809
+ Display fields are captured when `threads` is assigned. After a change, create and assign a new
31810
+ collection; changing an assigned record or mutating the assigned array does not update the view.
31811
+ `filter`, `groupBy`, row callbacks, and group contexts receive the original source records.
31812
+
31583
31813
  **Properties:** `threads: LyraChatThread[] = []` (attribute: false). `activeConversationId: string = ''`
31584
31814
  (attribute `active-conversation-id`) — data mode:
31585
31815
  marks the matching row `active`/`aria-current` and scrolls it into view. `searchable: boolean =
@@ -31691,6 +31921,21 @@ prefix: `row-item-base`, `row-item-active-indicator`, `row-item-select-button`,
31691
31921
  internal virtual-list shadow tree, so set them on `lr-thread-list` or any ancestor. They do not style
31692
31922
  marks returned by `renderRowContent` or any other hook.
31693
31923
 
31924
+ **Themeable control states:** `--lr-thread-list-group-toggle-hover-bg` (default
31925
+ `var(--lr-color-surface-raised)`), `--lr-thread-list-group-toggle-hover-color` (default
31926
+ `var(--lr-color-text)`), `--lr-thread-list-group-toggle-active-bg` (default `color-mix(in oklab,
31927
+ var(--lr-thread-list-group-toggle-hover-bg, var(--lr-color-surface-raised)),
31928
+ var(--lr-color-mix-partner) var(--lr-color-mix-active))`), and
31929
+ `--lr-thread-list-group-toggle-active-color` (default
31930
+ `var(--lr-thread-list-group-toggle-hover-color, var(--lr-color-text))`) style group-toggle hover
31931
+ and pressed states. `--lr-thread-list-row-action-hover-bg` (default
31932
+ `var(--lr-color-surface-raised)`), `--lr-thread-list-row-action-hover-color` (default
31933
+ `var(--lr-color-text)`), `--lr-thread-list-row-action-active-bg` (default `color-mix(in oklab,
31934
+ var(--lr-thread-list-row-action-hover-bg, var(--lr-color-surface-raised)),
31935
+ var(--lr-color-mix-partner) var(--lr-color-mix-active))`), and
31936
+ `--lr-thread-list-row-action-active-color` (default
31937
+ `var(--lr-thread-list-row-action-hover-color, var(--lr-color-text))`) do the same for row actions.
31938
+
31694
31939
  **Keep the two prefixes straight — they are different surfaces.** The `row-*` parts wrap _this_
31695
31940
  component's own render-callback output (`wrapRow`, `renderStart`, `renderExcerpt`,
31696
31941
  `renderRowContent`, `renderMeta`, `renderActions`); the `row-item-*` parts are the row item's
@@ -31950,12 +32195,12 @@ value to complete the update.
31950
32195
  **CSS parts:** `base` (the root wrapper, `display: contents`), `row`, `col`, `text` (built-in
31951
32196
  structural nodes only — a mapped lyra component exposes its own parts instead).
31952
32197
 
31953
- Caps: depth 32, 5,000 nodes, 100 visited props per node, and 100 unique warning keys plus one
31954
- deterministic suppression warning. The current document/registry generation deduplicates warnings;
31955
- binding-state-only re-resolution stays quiet, while replacing the root or registry releases prior
31956
- keys. Exported deterministic `nodeKey`/`nodePath` identity drives reconciliation. One bounded input
31957
- snapshot is shared by traversal, identity validation, pointer resolution, and rendering, so getters
31958
- beyond an admitted cap are never dereferenced.
32198
+ For predictable rendering, documents are limited to depth 32, 5,000 nodes, and 100 properties per
32199
+ node. Content beyond those size limits is omitted or truncated; malformed documents fail closed,
32200
+ clearing prior output and emitting `lr-render-error`. `document` is captured when assigned, so
32201
+ mutate a copy and assign it to update; `bindingState` updates bindings without changing that
32202
+ captured document or registry. Exported deterministic `nodeKey`/`nodePath` identity drives
32203
+ reconciliation.
31959
32204
 
31960
32205
  ```ts
31961
32206
  import { html } from "lit";
@@ -31984,10 +32229,10 @@ const view = html`<lr-widget-renderer
31984
32229
  ```
31985
32230
 
31986
32231
  For a controlled binding, use a per-instance registry and apply the event's requested value back to
31987
- `bindingState` (this one-field example binds `/name`). This is also the lean registration route: it imports
31988
- the side-effect-free renderer class, defines only `lr-widget-renderer`, and imports only the mapped
31989
- input registration. Do not import `widget-renderer.js` on this route; that entry intentionally
31990
- installs the full default registry.
32232
+ `bindingState` (this one-field example binds `/name`). The direct class route supplies the
32233
+ default type mappings but defines only `lr-widget-renderer`; register every mapped custom element
32234
+ you use yourself. The normal `widget-renderer.js` entry also registers the eight default mapped
32235
+ elements, so do not import it on this route.
31991
32236
 
31992
32237
  ```html
31993
32238
  <lr-widget-renderer id="bound-widget"></lr-widget-renderer>
@@ -32027,9 +32272,8 @@ renderer.addEventListener("lr-widget-state-change", (event) => {
32027
32272
 
32028
32273
  **Optional peer deps:** none new — the normal registration entry directly imports the eight mapped
32029
32274
  components (`markdown` keeps its own `marked`/`dompurify` optional-peer fallback). The manual class
32030
- route above is the verified lean path: its real peer-inclusive esbuild metafile excludes
32031
- `default-registry.js` and all eight default mapped class modules, while the consumer explicitly
32032
- imports only the component registrations its per-instance registry maps.
32275
+ route supplies the same default type mappings while leaving component registration under the
32276
+ consumer's control.
32033
32277
 
32034
32278
  ## `lr-voice-picker`
32035
32279
 
@@ -32077,6 +32321,10 @@ identically-named properties. `size: LyraSize = 'm'` (reflected) selects the sha
32077
32321
  `--lr-form-control-*` metrics. The separate preview button retains the library-wide 40px minimum
32078
32322
  hit area at compact tiers and grows with `l`/`xl`.
32079
32323
 
32324
+ `readonly: boolean = false` (reflected) mirrors `lr-model-select`: it blocks user typing and catalog
32325
+ commits while preserving focus, popup navigation, selection/copy, reset, submission, programmatic
32326
+ writes, and the preview actions.
32327
+
32080
32328
  The `label` property and `label` slot share one native label in the standard `form-control` frame.
32081
32329
  Slotted label content participates in the accessible name in both closed-dropdown and free-text
32082
32330
  modes; an explicit host `aria-label` remains the highest-precedence name.
@@ -32130,8 +32378,9 @@ outer pair. One bubbling/composed `lr-invalid` alias fires when native validity
32130
32378
  `[part="form-control-label"]`, retunable or suppressible through
32131
32379
  `--lr-form-control-required-content`, `--lr-form-control-required-color` and
32132
32380
  `--lr-form-control-required-offset`; and while the picker is barred from
32133
- constraint validation (own `disabled`, or an ancestor `<fieldset disabled>` — there is no `readonly`
32134
- here) it reports no violation and publishes neither `:state(invalid)` nor `:state(user-invalid)`.
32381
+ constraint validation (own `disabled` or `readonly`, or an ancestor `<fieldset disabled>`) it
32382
+ reports no violation and publishes neither `:state(invalid)` nor
32383
+ `:state(user-invalid)`.
32135
32384
 
32136
32385
  **CSS parts:** `form-control` (the complete field frame), `form-control-label`, `trigger` (closed-dropdown mode), `combobox`/`combobox-input`
32137
32386
  (free-text mode), `provider-badge`, `listbox`, `option`, `option-label`, `option-meta` (the quiet
@@ -32193,7 +32442,7 @@ grounding, and context state: transcript + composer in the main pane, and a deta
32193
32442
  assign new data to the properties as the host receives updates.
32194
32443
 
32195
32444
  This is the single component that binds the most of the provider-neutral vocabulary exported from
32196
- `@aceshooting/lyra-ui/ai` (`src/ai/types.ts`) at once; a host that already holds `ChatMessage[]`,
32445
+ `@aceshooting/lyra-ui/ai` at once; a host that already holds `ChatMessage[]`,
32197
32446
  `AgentRun`, `RetrievalChunk[]`, `Citation[]`, and `GroundingAssessment` can wire this up with no
32198
32447
  adapters.
32199
32448
 
@@ -32251,7 +32500,8 @@ Citation; truncated?: boolean; omittedTokens?: number; redactions?: ContextInspe
32251
32500
  the border and padding; a supplied `composer` slot keeps its own frame.
32252
32501
  - `composerValue: string = ''` (attribute `composer-value`) — controlled composer value
32253
32502
  - `composerStatus: ChatComposerStatus = 'idle'` (attribute `composer-status`) — `'idle' | 'sending' |
32254
- 'streaming'`, `lr-chat-composer`'s own union
32503
+ 'streaming'`, `lr-chat-composer`'s own union; invalid values read as `idle` without rewriting the
32504
+ host attribute
32255
32505
  - `composerPlaceholder: string = ''` (attribute `composer-placeholder`)
32256
32506
  - `composerMinRows: number = 1` (attribute `composer-min-rows`), `composerMaxRows: number = 8`
32257
32507
  (attribute `composer-max-rows`)
@@ -32327,12 +32577,14 @@ parse/highlight work; replacing that same-id part with `state: 'complete'` flush
32327
32577
  Citation badge ranks are precomputed in one linear pass per render, rather than rescanning and
32328
32578
  allocating every preceding part for each citation in a citation-heavy or growing message.
32329
32579
 
32330
- **Properties:** `parts: MessagePart[] = []` (attribute: false); `contentMode: 'plain' | 'markdown' =
32580
+ **Properties:** `parts: MessagePart[] = []` (attribute: false); `contentMode: MessagePartsContentMode =
32331
32581
  'markdown'` (attribute `content-mode`, reflected) and `showReasoning: boolean = true` (attribute
32332
32582
  `show-reasoning`, reflected, with string-aware true-default conversion);
32333
32583
  `renderPart?: MessagePartRenderer` (attribute: false), where returning `undefined` delegates that
32334
32584
  part to the built-in renderer; `accessibleLabel: string | null = null` (attribute `aria-label`).
32335
32585
 
32586
+ Unsupported direct or `content-mode` attribute values normalize and reflect as `markdown`.
32587
+
32336
32588
  `MessagePartRenderer = (part: MessagePart, index: number) => unknown`; `MessagePart` and its
32337
32589
  discriminated part shapes come from the `@aceshooting/lyra-ui/ai` subpath. Tool results are a strict
32338
32590
  success/error union: a success has `result` and cannot have `error`; an error has `error` and may
@@ -32412,6 +32664,7 @@ request. `label` names the prompt section; it is not generic field chrome.
32412
32664
  `autocomplete: string = ''`, `inputMode: string = ''` (attribute `inputmode`), and
32413
32665
  `enterKeyHint: string = ''` (attribute `enterkeyhint`) forward unchanged to the composed native
32414
32666
  textarea; empty string hints preserve the browser default.
32667
+ Invalid `status` values read as `idle` without rewriting the host attribute.
32415
32668
  `attachments: readonly LyraPromptInputAttachment[] = []` — `attachmentId` must be nonempty and
32416
32669
  unique; malformed rows and later duplicates are omitted first-wins before rendering and attachment
32417
32670
  events, and surviving chips reconcile by `attachmentId`. `attachmentCapabilities: readonly
@@ -32467,9 +32720,12 @@ replaces the built-in composer action.
32467
32720
  **Themeable custom properties:** `--lr-prompt-input-control-width` (default `--lr-size-12rem`) is
32468
32721
  the preferred width of each generated model, voice, and source control before wrapping.
32469
32722
 
32470
- Mention-popover focus transfer is generation-guarded: closing, disabling, disconnecting, adopting,
32471
- or replacing the query/data before its awaited focus step prevents stale focus. Empty `chips` and
32472
- `footer` wrappers are not rendered, so an absent optional region cannot create phantom spacing.
32723
+ An open mention or command popup remains open only while focus is in the primary textarea or that
32724
+ popup; moving focus to another prompt control or outside closes it. Arrow keys move focus to the
32725
+ active option. Enter or Tab accepting an option is handled before textarea submission. Escape
32726
+ restores the textarea's prior ARIA and selection. If the popup closes, becomes unavailable, or its
32727
+ input/items change before focus moves, no move occurs. Empty `chips` and `footer` wrappers are not rendered, so an absent optional region cannot
32728
+ create phantom spacing.
32473
32729
 
32474
32730
  **Optional peer deps:** none of its own.
32475
32731
 
@@ -32496,6 +32752,12 @@ Item ids are occurrence identities. Empty ids and later duplicates are ignored b
32496
32752
  proposing a mutation, preserving one unambiguous `itemId`. Attachment names render visibly for both
32497
32753
  editable and read-only rows; the host `label` is also the visible queue heading.
32498
32754
 
32755
+ Supported item and attachment fields are read once when `items` is assigned; create and reassign a
32756
+ new collection after changes, because changing an assigned record or reassigning the same mutated
32757
+ array does not update the view. Rows or attachments without valid direct data are ignored. Duplicate IDs are resolved
32758
+ after validation, so the first valid item wins. `metadata` is opaque and retains identity in
32759
+ proposed queue/send-now payloads, while emitted items are new frozen snapshots.
32760
+
32499
32761
  **Events:** `lr-queue-change` (`PromptQueueChangeDetail = { items, reason, itemId }`, with
32500
32762
  `reason: 'edit' | 'remove' | 'reorder'`), `lr-send-now` (`{ item }`). The queue is controlled:
32501
32763
  these events propose complete next values without mutating `items`.
@@ -32613,6 +32875,50 @@ remain host-owned.
32613
32875
  import "@aceshooting/lyra-ui/components/conversation/realtime-session/realtime-session.js";
32614
32876
  ```
32615
32877
 
32878
+ ## Consumer integration notes
32879
+
32880
+ - **Markdown:** GFM task checkboxes stay disabled. When a checkbox has nonblank primary inline
32881
+ text, that primary inline text names the checkbox; nested-list text is excluded and an otherwise blank
32882
+ task receives no invented label. For an intercepted internal link that overlaps a highlight,
32883
+ `lr-highlight-activate` fires before `lr-link-click` for pointer and Enter activation;
32884
+ external links keep their native navigation.
32885
+ - **Catalog controls:** `lr-model-select` and `lr-voice-picker` reflect `readonly`. It blocks user
32886
+ typing and catalog commits without disabling focus, popup navigation, selection/copy, reset,
32887
+ submission, or programmatic writes; voice previews remain available. They are barred from native
32888
+ constraint validation while disabled, readonly, or disabled by a fieldset. Voice preview actions
32889
+ expose the shared hover/pressed fill and icon hooks in both standalone and catalog-row layouts.
32890
+ - **Status values:** invalid direct or attribute status writes on `lr-chat-composer` normalize and
32891
+ reflect to `idle`. `lr-prompt-input` and `lr-agent-workspace` read invalid forwarded status as the
32892
+ safe `idle` state without rewriting their host attributes.
32893
+ - **Feedback toolbar:** `lr-message-actions.feedbackPending` identifies a built-in feedback request
32894
+ awaiting settlement. Pass the frozen `submissionId` from `lr-feedback-submit` to
32895
+ `finalizePendingSubmit()` or `revertPendingSubmit()`. Logical toolbar actions may implement
32896
+ `releaseTabIndex()` to restore an unchanged authored tabindex when the toolbar stops managing it;
32897
+ a later author write is never overwritten.
32898
+ - **Message content:** `MessagePartsContentMode` is exported. Unsupported direct or
32899
+ `content-mode` attribute values normalize and reflect as `markdown`.
32900
+ - **Prompt queues:** items and attachments are captured on assignment; create and reassign a new
32901
+ collection after changes, because changing an assigned record or reassigning the same mutated
32902
+ array does not update the view.
32903
+ Invalid rows are ignored, and the first valid duplicate id wins. A suggestion popup stays open
32904
+ only while focus remains in its textarea or popup; accepting an option handles Enter or Tab before
32905
+ textarea submission.
32906
+ - **Push-to-talk:** releasing hold mode while permission is pending leaves that request eligible
32907
+ only for the next same-document held press; otherwise a later grant is discarded. A held press
32908
+ during a stopping take starts after the current take ends. Disablement, disconnection, or a
32909
+ cross-document move prevents a later permission result from starting or finishing capture.
32910
+ - **Code blocks:** malformed highlight-line segments are independently ignored while valid segments
32911
+ remain. When Shiki is unavailable, readable plain text remains available.
32912
+ - **Threads:** `lr-thread-list` captures display fields when `threads` is assigned; its render,
32913
+ filter, and grouping callbacks receive the original records, so create and reassign a new
32914
+ collection to update. Changing an assigned record or reassigning the same mutated array does not
32915
+ update the view.
32916
+ Group toggles and row actions have independent hover/pressed background and foreground tokens.
32917
+ - **Audio visualizer:** an author-supplied `role` wins; the component supplies `role="img"` only
32918
+ when absent. With a working observer it waits for its first valid visible entry and pauses
32919
+ offscreen; unavailable/broken observation renders eagerly. Canvas input is clamped after gain to
32920
+ `-1..1` for waveforms and `0..1` for bars.
32921
+
32616
32922
  ## Exported TypeScript contracts
32617
32923
 
32618
32924
  These named interfaces and helper signatures are available to typed integrations. They are grouped by capability so the component sections above can stay focused.
@@ -32622,6 +32928,9 @@ These named interfaces and helper signatures are available to typed integrations
32622
32928
  collapsed: unknown;
32623
32929
  }`
32624
32930
 
32931
+ - **`components-conversation-chat-composer-chat-composer-contracts`** — Supporting data types and helpers for this component family.
32932
+ `normalizeChatComposerStatus(value: unknown): ChatComposerStatus`
32933
+
32625
32934
  - **`components-conversation-checkpoint-checkpoint-contracts`** — Supporting data types and helpers for this component family.
32626
32935
  `CheckpointRestoreDetail {
32627
32936
  checkpointId: unknown;
@@ -32769,6 +33078,7 @@ These named interfaces and helper signatures are available to typed integrations
32769
33078
  options: unknown;
32770
33079
  setTabIndex: unknown;
32771
33080
  tabIndex: unknown;
33081
+ releaseTabIndex?(): void;
32772
33082
  matchesEventPath: unknown;
32773
33083
  path: unknown;
32774
33084
  }`
@@ -32789,6 +33099,7 @@ These named interfaces and helper signatures are available to typed integrations
32789
33099
  rating: unknown;
32790
33100
  reasonIds: unknown;
32791
33101
  comment: unknown;
33102
+ readonly submissionId: string;
32792
33103
  }`
32793
33104
 
32794
33105
  - **`components-conversation-model-select-model-select-contracts`** — Supporting data types and helpers for this component family.
@@ -33001,8 +33312,8 @@ referenced: `--lr-color-text-quiet`, `--lr-color-surface`, `--lr-color-border`,
33001
33312
  </script>
33002
33313
  ```
33003
33314
 
33004
- The default slot's tooltip is positioned with the same `internal/positioner.js` `place()` helper
33005
- `<lr-combobox>` uses for its listbox (`placement: 'top-start'`), and appears/disappears instantly
33315
+ The default slot's tooltip uses the same `'top-start'` placement as `<lr-combobox>`'s listbox, and
33316
+ appears/disappears instantly
33006
33317
  on hover/focus/blur/mouseleave with no fade transition and no "pointer moved into the tooltip"
33007
33318
  tracking — it's documented as read-only preview content, not an interactive surface meant to retain
33008
33319
  focus of its own. `denied` gets its own warning-toned glyph and color (a policy rejection, not a
@@ -33170,12 +33481,11 @@ registerToolRenderer("run_query", {
33170
33481
  `registry` prop is set
33171
33482
  - `findToolRenderer(toolName: string, payload: unknown, registry?: ToolRendererRegistry):
33172
33483
  ToolRendererDefinition | undefined` — the dispatch function `<lr-tool-result-view>` calls
33173
- internally on every resolve; exposed for direct use/testing too
33484
+ internally on every resolve; exposed for direct use too
33174
33485
  - `loadToolRenderer(def: ToolRendererDefinition): Promise<DirectToolRendererDefinition>` — resolves `def`
33175
33486
  to a definition guaranteed to carry a real `render`, awaiting/unwrapping `def.load()` when present
33176
33487
  (or returning `def` unchanged otherwise)
33177
- - `clearToolRenderers(): void` — test-only utility that empties the default registry and its
33178
- `load()` cache, so one test's `registerToolRenderer()` calls can't leak into the next
33488
+ - `clearToolRenderers(): void` — clears the default registry and its `load()` cache
33179
33489
 
33180
33490
  **Dispatch order** (`findToolRenderer`), exactly as `<lr-tool-result-view>`'s own `resolve()` uses
33181
33491
  it:
@@ -33445,8 +33755,8 @@ the desired detail values after that work succeeds. `lr-close`
33445
33755
  (`detail: ToolSelectDialogCloseReason` — fired exactly once per dismissal, via Escape, a backdrop
33446
33756
  click when `lightDismiss` is enabled, or a `close()` call), and no-detail `focus`/`blur` events
33447
33757
  re-dispatched when the internal search input gains or loses focus.
33448
- Native `input`/`change` and prefixed `lr-input` implementation events from the built-in checkbox and
33449
- switch controls stop at the dialog boundary; listen for the single aggregate `lr-change` proposal.
33758
+ Native `input`/`change` and prefixed `lr-input` events from the built-in checkbox and switch
33759
+ controls stop at the dialog boundary; listen for the single aggregate `lr-change` proposal.
33450
33760
 
33451
33761
  **Slots:** `footer` — optional action buttons (e.g. a "Done" button), rendered in a bottom row. Changes
33452
33762
  already apply live via `lr-change`, so this slot is purely optional; only visually shown once it has
@@ -33582,6 +33892,8 @@ pending duration/toggle accent without changing the shared brand token;
33582
33892
  `--lr-thinking-panel-compact-header-padding` (default `var(--lr-space-2xs) var(--lr-space-s)`) —
33583
33893
  `[part="header"]` padding while `compact`; `--lr-thinking-panel-compact-header-gap` (default
33584
33894
  `var(--lr-space-2xs)`) — gap between the toggle, label, and duration while `compact`; and
33895
+ `--lr-thinking-panel-compact-header-font-size` (default `var(--lr-font-size-sm)`) — font size of
33896
+ `[part="header"]` while `compact`; and
33585
33897
  `--lr-thinking-panel-compact-body-padding` (default `var(--lr-space-s)`) — `[part="body"]`
33586
33898
  padding while `compact`. Plus shared
33587
33899
  `--lr-color-border`/`-surface`/`-text`/`-text-quiet`/`-brand`/`-brand-quiet`,
@@ -34037,8 +34349,8 @@ fired once up front at connect time and after every effective change; serializat
34037
34349
  publish their root message as `errors.base` and `formError`), and no-detail `focus`/`blur` events for
34038
34350
  generated native text/number inputs. The composed
34039
34351
  `<lr-select>` controls already bubble their own focus/blur bridges through the host.
34040
- Their implementation events (`input`, `change`, `lr-change`, select show/hide, and option mutation)
34041
- are contained at the form boundary; consumers receive the single form-level `lr-input` contract.
34352
+ Nested control events (`input`, `change`, `lr-change`, select show/hide, and option mutation) are
34353
+ contained at the form boundary; consumers receive the single form-level `lr-input` contract.
34042
34354
  `lr-invalid` (no detail) is the bubbling/composed, cancelable alias emitted when the complete
34043
34355
  parameter form fails a native validity check; preventing it also prevents the native `invalid`
34044
34356
  event's default validation UI.
@@ -34254,9 +34566,9 @@ around either the slotted content or the plain `value` text).
34254
34566
 
34255
34567
  - `HTMLElement.textContent` read on a shadow-DOM wrapper containing a `<slot>` does NOT include the
34256
34568
  slot's assigned/projected light-DOM content — only literal fallback children of the `<slot>` tag
34257
- itself (there are none here). Asserting against `[part="value"]`'s own `.textContent` to check
34258
- rendered slotted content will read as empty even when the component is rendering correctly;
34259
- assert against the slot's `assignedNodes()`/`assignedElements()` instead.
34569
+ itself (there are none here). Reading `[part="value"]`'s own `.textContent` yields an empty value
34570
+ even when slotted content is rendering correctly; use the slot's
34571
+ `assignedNodes()`/`assignedElements()` instead.
34260
34572
 
34261
34573
  ---
34262
34574
 
@@ -34505,13 +34817,22 @@ of the text last announced while `announce-output` is set).
34505
34817
  `[part="announcer"]` is a styling and inspection surface only — it carries **no** live-region role
34506
34818
  of its own. The announcement itself goes to the library's shared **light-DOM** polite region,
34507
34819
  appended to the consumer's `<body>` and marked `data-lr-live-region="polite"`, because a live
34508
- region inside a shadow root is not reliably announced (JAWS with Firefox ignores one outright). A
34509
- test therefore asserts against that shared region, not `::part(announcer)`; the part remains the
34510
- right hook for styling, and for reading back what the terminal last announced.
34820
+ region inside a shadow root is not reliably announced (JAWS with Firefox ignores one outright).
34821
+ Inspect the shared region, not `::part(announcer)`, when reading an announcement; the part remains
34822
+ the right hook for styling and for reading back what the terminal last announced.
34511
34823
 
34512
34824
  **Themeable custom properties:** `--lr-terminal-height` (default `var(--lr-size-20rem)`) — the
34513
34825
  viewport's block size; not declared on `:host`, so it is inherited from the host or any ancestor.
34514
- `--lr-terminal-highlight-accent-bg` (default `var(--lr-color-brand-quiet)`),
34826
+ `--lr-terminal-surface-color` (default `var(--lr-color-surface-raised)`) controls the card-frame
34827
+ background and the fallback foreground for inverse ANSI segments without an explicit background;
34828
+ `frame="plain"` remains transparent. `--lr-terminal-toolbar-button-hover-bg` (default
34829
+ `var(--lr-color-brand-quiet)`) and `--lr-terminal-toolbar-button-active-bg` (default
34830
+ `color-mix(in oklab, var(--lr-terminal-toolbar-button-hover-bg, var(--lr-color-brand-quiet)),
34831
+ var(--lr-color-mix-partner) var(--lr-color-mix-active))`) control the copy and download buttons.
34832
+ `--lr-terminal-line-hover-bg` (default `var(--lr-color-brand-quiet)`) and
34833
+ `--lr-terminal-line-active-bg` (default `color-mix(in oklab, var(--lr-terminal-line-hover-bg,
34834
+ var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) control
34835
+ ordinary rendered lines. `--lr-terminal-highlight-accent-bg` (default `var(--lr-color-brand-quiet)`),
34515
34836
  `--lr-terminal-highlight-success-bg` (default `var(--lr-color-success-quiet)`),
34516
34837
  `--lr-terminal-highlight-warning-bg` (default `var(--lr-color-warning-quiet)`),
34517
34838
  `--lr-terminal-highlight-danger-bg` (default `var(--lr-color-danger-quiet)`), and
@@ -34651,8 +34972,8 @@ against the new tint as well.
34651
34972
 
34652
34973
  ## `lr-activity-feed`
34653
34974
 
34654
- An append-only streaming log of granular agent actions ("Searching the web…", "Read
34655
- src/index.ts"), collapsing to a localized "Completed N steps" summary once the run is over. Entries
34975
+ An append-only streaming log of granular agent actions ("Searching the web…", "Read the
34976
+ application entry point"), collapsing to a localized "Completed N steps" summary once the run is over. Entries
34656
34977
  never change state once added — a step whose status mutates in place belongs to `<lr-task-list>`
34657
34978
  instead. Implements the shared follow (stick-to-bottom) contract. At/above `virtualizeAt`
34658
34979
  entries, the body renders through an internal `<lr-virtual-list>` instead of a plain keyed list.
@@ -34669,13 +34990,14 @@ unset. `mode: 'live' | 'post-hoc' =
34669
34990
  `label?: string` — omission localizes `activityFeedLabel` (`'Activity'` in the built-in English
34670
34991
  catalog), while any supplied string is a verbatim override, including `'Activity'` under a
34671
34992
  non-English `.strings` catalog and `''`. A present host `aria-label` names the owned list in both
34672
- plain and virtualized rendering paths while `label` remains the visible header text
34993
+ plain and virtualized rendering paths while `label` remains the visible header text. Host
34994
+ `aria-labelledby` and `aria-describedby` likewise reach that semantic list in both rendering paths —
34673
34995
  `showTimestamps: boolean = false` (attribute `show-timestamps`),
34674
34996
  `formatTimestamp?: (date: Date) => string` (attribute: false), `renderText?: (entry: ActivityEntry)
34675
34997
  => TemplateResult` (attribute: false) — overrides the default plain-text `entry-text` rendering with
34676
34998
  arbitrary rich content (e.g. rendered markdown, or markdown plus a trailing tool-call chip list),
34677
- identically whether or not the feed is currently virtualized; fully replaces `[part="entry-text"]`
34678
- rather than augmenting it, and `virtualizeAt: number = 199` (attribute
34999
+ identically whether or not the feed is currently virtualized; replaces the plain text **inside**
35000
+ the persistent `[part="entry-text"]` wrapper rather than removing that part, and `virtualizeAt: number = 199` (attribute
34679
35001
  `virtualize-at`).
34680
35002
 
34681
35003
  **Events:** `lr-toggle` (`detail: { expanded }`, the header was activated) and
@@ -35098,7 +35420,7 @@ cancelable. Retry is available for `error` and `cancelled`.
35098
35420
  **Properties:**
35099
35421
 
35100
35422
  - `run: AgentRun | null = null` (attribute: false) — **`AgentRun`, imported from
35101
- `@aceshooting/lyra-ui/ai`** (`src/ai/types.ts`): `{ id: string; status: AgentStatus; startedAt?:
35423
+ `@aceshooting/lyra-ui/ai`**: `{ id: string; status: AgentStatus; startedAt?:
35102
35424
  number; endedAt?: number; model?: string; costEstimate?: number; steps: readonly AgentStep[] }`, where
35103
35425
  `AgentStatus { kind: AgentStatusKind; message?: string }` and `AgentStep { id: string; kind:
35104
35426
  string; label: string; status: AgentStatus; startedAt?: number; endedAt?: number }`. All timestamps
@@ -35281,8 +35603,8 @@ Filterable and taggable evaluation-example list with add, remove, import, and ex
35281
35603
 
35282
35604
  - `examples: readonly EvalExample[] = []` (attribute: false) — `EvalExample { id: string; input: string;
35283
35605
  expectedOutput?: string; tags?: readonly string[]; metadata?: Record<string, unknown> }` (exported here).
35284
- Deliberately its own small shape rather than reusing anything from `src/ai/types.ts` none of that
35285
- module's interfaces models "one row of a labeled eval dataset". `input`/`expectedOutput` are plain
35606
+ It is a dedicated dataset-row shape; no shared agent type models a labeled evaluation row.
35607
+ `input`/`expectedOutput` are plain
35286
35608
  strings (not structured payloads), rendered as plain text by every column's `cell()`. Fully
35287
35609
  controlled: add/remove/import/export are all _requests_; the host mutates and passes the array
35288
35610
  back. Empty/blank ids and later duplicate ids are omitted before selection, filtering, mutation requests, and the
@@ -35892,6 +36214,42 @@ import "@aceshooting/lyra-ui/components/agent-tools/subagent-panel/subagent-pane
35892
36214
  - `--lr-subagent-panel-progress-track` — Progress track. Default: `var(--lr-color-border)`.
35893
36215
  - `--lr-subagent-panel-progress-fill` — Progress fill. Default: `var(--lr-color-brand)`.
35894
36216
 
36217
+ ## Consumer integration notes
36218
+
36219
+ - **Tool selection:** `lr-tool-select-dialog` inspects at most 10,000 supplied positions. A usable
36220
+ row is a plain or null-prototype record with nonblank string `id` and `name`; malformed rows are
36221
+ omitted and the first usable duplicate wins. `selectedToolIds` independently retains its first
36222
+ nonblank ids, including ids that are not presently offered, and `lr-change` carries that bounded
36223
+ canonical sequence.
36224
+ - **Parameter schemas:** `lr-tool-param-form` recursively admits only own-data fields from arrays,
36225
+ plain records, and null-prototype records. Unsafe branches are omitted while safe siblings remain;
36226
+ they cannot enter serialized values or `FormData`. A malformed enum omits only that field and
36227
+ leaves schema-shape validity false. Its semantic owner renders `aria-invalid="true"` only after
36228
+ interaction or `reportValidity()` when invalid and not barred from validation; otherwise it
36229
+ explicitly renders `"false"`.
36230
+ - **Localized metrics:** `lr-span-waterfall` and `lr-test-results` format visual and spoken metrics
36231
+ with the effective locale, joining row and toggle labels with the localized accessible-label
36232
+ separator.
36233
+ - **Terminal styling:** `--lr-terminal-surface-color` defaults to
36234
+ `var(--lr-color-surface-raised)` for the card frame and inverse ANSI fallback foreground; a plain
36235
+ frame stays transparent. `--lr-terminal-toolbar-button-hover-bg`,
36236
+ `--lr-terminal-toolbar-button-active-bg`, `--lr-terminal-line-hover-bg`, and
36237
+ `--lr-terminal-line-active-bg` independently theme toolbar-button and ordinary-line hover/pressed
36238
+ states; highlighted lines retain their tone-specific backgrounds.
36239
+ - **Approval lifecycle:** when a selected pending request disappears or resolves,
36240
+ `lr-approval-close.detail.reason` can be `'request-invalidated'`; selection and open state clear
36241
+ before that noncancelable event.
36242
+ - **Tool result slots:** explicitly assigning `slot=""` is default detail content and can enable the
36243
+ tool-call tooltip; named slots do not. A renderer's synchronous `reportStatus()` applies only to
36244
+ its current render attempt, so late or stale reports are ignored.
36245
+ - **Trace visibility:** `lr-agent-trace` contains the nested graph legend's proposal event. Its
36246
+ public `lr-span-visibility-change` event reports the resulting `{ hiddenKinds }` state. If an
36247
+ integration exposes the nested `lr-graph-legend`, attach a veto listener to that legend rather
36248
+ than to the wrapper.
36249
+ - **Schema viewer input:** `lr-json-schema-viewer` uses a bounded descriptor-safe own-data snapshot.
36250
+ It recurses through arrays, plain records, and null-prototype records only; unsupported or unsafe
36251
+ branches are omitted while valid siblings and the valid prefix remain available.
36252
+
35895
36253
  ## Exported TypeScript contracts
35896
36254
 
35897
36255
  These named interfaces and helper signatures are available to typed integrations. They are grouped by capability so the component sections above can stay focused.
@@ -36698,9 +37056,12 @@ description?: string; category?: string; keywords?: string[]; icon?: unknown; di
36698
37056
  first-appearance-ordered headings, `disabled` renders an item visible but not draggable/placeable.
36699
37057
  A non-array value is treated as empty. Rows require nonblank string `type` and `label` values;
36700
37058
  malformed optional `description`, `category`, `keywords`, or `disabled` values omit only that row,
36701
- preserving later valid entries
37059
+ preserving later valid entries. At most 10,000 positions are examined through own data
37060
+ descriptors; accessor-backed rows are omitted without reserving later valid rows. The frozen
37061
+ projection drives display while `lr-select.detail.item` retains the original admitted identity
36702
37062
  - `label?: string` — accessible name for the search field/listbox; omission uses the localized
36703
- palette label, while an explicit empty string stays empty
37063
+ palette label. An omitted, empty, or whitespace-only value uses that fallback without changing
37064
+ the raw property readback
36704
37065
  - `reorderable: boolean = false` (reflected) — opts into Ctrl/Cmd+ArrowUp/ArrowDown keyboard
36705
37066
  reordering of the catalog. Unset, no `lr-reorder` is ever emitted and Ctrl/Cmd+Arrow keeps
36706
37067
  behaving exactly like a plain Arrow press
@@ -36783,8 +37144,10 @@ string; shape?: 'circle' | 'square' | 'diamond' }`, the shared `lr-graph.nodeTyp
36783
37144
  `aria-label` makes the host the sole overall owner (the wrapper omits its duplicate role/name);
36784
37145
  an explicitly empty host label stays empty on the wrapper
36785
37146
 
36786
- **Events:** `lr-visibility-change` (`detail: { hiddenTypes }`, the complete updated array, fired
36787
- after each toggle).
37147
+ **Events:** cancelable `lr-before-visibility-change` (`detail: { hiddenTypes }`, a frozen complete
37148
+ next array) fires before a toggle changes state or announces it. Preventing it suppresses all three.
37149
+ `lr-visibility-change` (`detail: { hiddenTypes }`, the complete updated array) fires after an
37150
+ accepted assignment and announcement.
36788
37151
 
36789
37152
  **Slots:** none.
36790
37153
 
@@ -37252,8 +37615,8 @@ Plus shared tokens otherwise.
37252
37615
  **Known gotchas:**
37253
37616
 
37254
37617
  - `title` and `open-button` are split into two separate parts (rather than one dual-part-name
37255
- element) because an exact-match `[part="..."]` CSS attribute selector as this component's own
37256
- tests use — cannot match a multi-token `part` attribute value.
37618
+ element) because an exact-match `[part="..."]` CSS attribute selector cannot match a multi-token
37619
+ `part` attribute value.
37257
37620
 
37258
37621
  ---
37259
37622
 
@@ -37819,7 +38182,7 @@ and `lr-citation-badge` for each evidence entry.
37819
38182
  **Properties:**
37820
38183
 
37821
38184
  - `assessment: GroundingAssessment | null = null` (attribute: false) — **`GroundingAssessment`,
37822
- imported from `@aceshooting/lyra-ui/ai`** (`src/ai/types.ts`): `{ supportedClaims: number;
38185
+ imported from `@aceshooting/lyra-ui/ai`**: `{ supportedClaims: number;
37823
38186
  unsupportedClaims: number; coverage: number; confidence?: number; warnings?: string[];
37824
38187
  claims?: GroundedClaim[] }`, where `coverage` and `confidence` are 0–1 fractions. `null` renders
37825
38188
  the empty state
@@ -37842,16 +38205,16 @@ label?: string }`. Independent of `assessment`; empty omits the whole evidence s
37842
38205
  level used by both warnings and evidence sections; `'none'` keeps the visual text without
37843
38206
  exposing a heading role, and invalid untyped values fall back to level 3
37844
38207
 
37845
- Direct citations and `assessment.claims` are canonicalized independently by nonblank `id` before
37846
- counts, child composition, rendering, or events. Malformed rows and later duplicate ids are omitted;
37847
- the first valid occurrence wins.
38208
+ Direct citations and `assessment.claims` are keyed independently by nonblank `id` before counts,
38209
+ rendering, or events. Usable display fields are captured once while emitted selected claim/citation
38210
+ objects retain their original identity. Malformed rows and later duplicate ids are omitted; the
38211
+ first valid occurrence wins.
37848
38212
 
37849
38213
  **Events:** `lr-citation-select` (`detail: CitationSelectEventDetail` from
37850
38214
  `@aceshooting/lyra-ui/ai` = `{ citation: Citation }`) — emitted when an evidence badge is activated.
37851
38215
  The inner `lr-citation-badge`'s generic activation is stopped at this composition boundary; this
37852
- richer event exists because a bare `sourceId`/`index` pair can't tell a host which exact evidence
37853
- _span_ to jump to. The composed `lr-claim-evidence` also surfaces
37854
- `lr-claim-select` (`detail: { claim }`) unchanged when a claim is activated.
38216
+ richer event exists because a bare `sourceId`/`index` pair cannot identify the exact evidence span.
38217
+ The summary emits `lr-claim-select` (`detail: { claim }`) when a claim is activated.
37855
38218
 
37856
38219
  **Slots:** none.
37857
38220
 
@@ -37863,7 +38226,7 @@ row), `warnings` (omitted when there are none), `warnings-heading`, `warnings-co
37863
38226
  its semantics survive list-style resets),
37864
38227
  `evidence-item` (one `<li>` containing a badge + always-visible label/span text),
37865
38228
  `evidence-label` (omitted when `Citation.label` is unset), `evidence-span` (the formatted
37866
- `Citation.span` range, omitted when unset), `claims` (the composed claim-evidence audit), `empty`
38229
+ `Citation.span` range, omitted when unset), `claims` (the claim/evidence region), `empty`
37867
38230
  (shown when `assessment` is `null`).
37868
38231
 
37869
38232
  **Themeable custom properties:** shared tokens only.
@@ -37931,7 +38294,7 @@ announcement itself goes to the library's shared **light-DOM** assertive region,
37931
38294
  consumer's `<body>` and marked `data-lr-live-region="assertive"`, because a live region inside a
37932
38295
  shadow root is not reliably announced (JAWS with Firefox ignores one outright). What is announced
37933
38296
  is unchanged: only failures added or transitioned _after_ mount, so historical failed rows stay
37934
- visible without being re-announced. Assert against that document-level region rather than
38297
+ visible without being re-announced. Read that document-level region rather than
37935
38298
  `::part(failure-live)`.
37936
38299
 
37937
38300
  In virtualized mode (above `virtualizeAt`) the rows live in the internal
@@ -37970,7 +38333,8 @@ errorMessage?: string }` (all four types exported here), where
37970
38333
  `syncStatus === 'error'`. `id`/`name` follow `DocumentRef`'s spirit, but a source is a _connector
37971
38334
  feeding_ documents, not a document, so the rest of the fields are its own
37972
38335
  - `label?: string` — heading text and the table's accessible name; omission uses the localized
37973
- knowledge-base label, while an explicit empty string stays empty
38336
+ knowledge-base label. An explicit empty string keeps the visible heading empty while the nested
38337
+ table still takes the localized default as its accessible name
37974
38338
  - `hideSummary: boolean = false` (attribute `hide-summary`, reflected) — hides the aggregate
37975
38339
  total/synced/syncing/needs-attention row
37976
38340
  - `hideCreate: boolean = false` (attribute `hide-create`, reflected) — hides the "Add source"
@@ -37998,6 +38362,14 @@ unset), `sync-cell`, `sync-badge`, `sync-timestamp`, `sync-error`, `health-cell`
37998
38362
  `document-count` (omitted when unset), `permission-badge` (omitted when `permission` is unset),
37999
38363
  `actions-menu`, `actions-trigger` (the kebab `<button>`).
38000
38364
 
38365
+ The 13 row parts — `name-cell`, `source-name`, `source-type`, `sync-cell`, `sync-badge`,
38366
+ `sync-timestamp`, `sync-error`, `health-cell`, `health-badge`, `document-count`,
38367
+ `permission-badge`, `actions-menu`, and `actions-trigger` — are forwarded from the composed table
38368
+ through `[part="table"]`/`exportparts`, so they are styleable as
38369
+ `lr-knowledge-base::part(actions-trigger)`. `actions-trigger` is the forwarded kebab button: it
38370
+ inherits the row font, has the shared `--lr-icon-button-size` minimum hit area (40px by default),
38371
+ and keeps independent hover, pressed, and focus treatment.
38372
+
38001
38373
  **Themeable custom properties:** shared tokens only.
38002
38374
 
38003
38375
  **Optional peer deps:** none.
@@ -38219,7 +38591,7 @@ text verbatim. Large sets window through an internal `lr-virtual-list`.
38219
38591
  **Properties:**
38220
38592
 
38221
38593
  - `chunks: RetrievalChunk[] = []` (attribute: false) — **`RetrievalChunk`, imported from
38222
- `@aceshooting/lyra-ui/ai`** (`src/ai/types.ts`): `{ id: string; text: string; score: number;
38594
+ `@aceshooting/lyra-ui/ai`**: `{ id: string; text: string; score: number;
38223
38595
  source: DocumentRef; metadata?: Record<string, unknown>; rank?: number; locator?: DocumentLocator;
38224
38596
  queryId?: string; stage?: string; traceId?: string; scores?: RetrievalScoreBreakdown }`. The raw,
38225
38597
  unsorted/ungrouped result set; host-owned. Blank ids and later duplicate ids are omitted
@@ -38725,6 +39097,16 @@ import "@aceshooting/lyra-ui/components/retrieval/rag-eval-dashboard/rag-eval-da
38725
39097
  `showClaims: boolean = true`; `lr-retrieval-results` forwards `RetrievalChunk.locator` as the
38726
39098
  document-viewer-compatible `anchor` in `lr-chunk-open`.
38727
39099
 
39100
+ ## Consumer integration notes
39101
+
39102
+ - **Explorer legend:** observe `lr-hidden-types-change` on
39103
+ `lr-knowledge-graph-explorer` for an accepted visibility change. A visibility proposal can be
39104
+ vetoed only from the legend control when an integration renders or owns one separately.
39105
+ - **Projected records:** `lr-memory-panel` and `lr-claim-evidence` capture usable display/action
39106
+ fields when their collections are assigned. Unsafe or malformed branches are omitted while valid
39107
+ siblings remain; selected/action event details retain the original record where that identity is
39108
+ part of the public contract. Reassign a new collection to update the rendered projection.
39109
+
38728
39110
  ## Exported TypeScript contracts
38729
39111
 
38730
39112
  These named interfaces and helper signatures are available to typed integrations. They are grouped by capability so the component sections above can stay focused.