@aceshooting/lyra-ui 11.2.0 → 12.1.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 (222) hide show
  1. package/CHANGELOG.md +407 -0
  2. package/README.md +11 -8
  3. package/custom-elements.json +1 -1
  4. package/dist/all.d.ts +1 -0
  5. package/dist/all.js +1 -1
  6. package/dist/autoloader.js +1 -1
  7. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +0 -1
  8. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
  9. package/dist/components/charts/chart/chart.class.d.ts +13 -1
  10. package/dist/components/charts/chart/histogram-bin.d.ts +0 -1
  11. package/dist/components/charts/chart/histogram-bin.js +1 -1
  12. package/dist/components/charts/chart/lite-chart.class.d.ts +22 -9
  13. package/dist/components/charts/chart/lite-chart.class.js +6 -6
  14. package/dist/components/conversation/code-block/code-block-shared.d.ts +4 -54
  15. package/dist/components/conversation/code-block/code-block-shared.js +1 -1
  16. package/dist/components/conversation/code-block/shiki-types.d.ts +2 -1
  17. package/dist/components/conversation/generation-metrics/generation-metrics.class.js +1 -1
  18. package/dist/components/conversation/model-select/model-select.class.d.ts +0 -3
  19. package/dist/components/conversation/model-select/model-select.class.js +1 -1
  20. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
  21. package/dist/components/conversation/voice-picker/voice-picker.class.d.ts +0 -1
  22. package/dist/components/conversation/voice-picker/voice-picker.class.js +1 -1
  23. package/dist/components/data/data-grid/data-grid.class.js +1 -1
  24. package/dist/components/data/funnel/funnel.class.d.ts +92 -0
  25. package/dist/components/data/funnel/funnel.class.js +25 -0
  26. package/dist/components/data/funnel/funnel.d.ts +1 -0
  27. package/dist/components/data/funnel/funnel.js +1 -0
  28. package/dist/components/data/funnel/funnel.styles.d.ts +1 -0
  29. package/dist/components/data/funnel/funnel.styles.js +127 -0
  30. package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +0 -1
  31. package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
  32. package/dist/components/data/heatmap/heatmap.class.d.ts +199 -14
  33. package/dist/components/data/heatmap/heatmap.class.js +30 -22
  34. package/dist/components/data/heatmap/heatmap.styles.js +36 -0
  35. package/dist/components/data/index.d.ts +1 -0
  36. package/dist/components/data/index.js +1 -1
  37. package/dist/components/data/table/table.class.d.ts +18 -4
  38. package/dist/components/data/table/table.class.js +2 -2
  39. package/dist/components/data/table/table.styles.js +2 -1
  40. package/dist/components/data/timeline/timeline-cluster.d.ts +1 -0
  41. package/dist/components/data/timeline/timeline-cluster.js +1 -0
  42. package/dist/components/data/timeline/timeline-item.class.d.ts +17 -2
  43. package/dist/components/data/timeline/timeline-item.class.js +13 -2
  44. package/dist/components/data/timeline/timeline-item.styles.js +65 -0
  45. package/dist/components/data/timeline/timeline.class.d.ts +83 -27
  46. package/dist/components/data/timeline/timeline.class.js +3 -3
  47. package/dist/components/data/timeline/timeline.d.ts +1 -0
  48. package/dist/components/data/timeline/timeline.js +1 -1
  49. package/dist/components/data/timeline/timeline.styles.js +14 -0
  50. package/dist/components/forms/button/button.class.js +1 -1
  51. package/dist/components/forms/checkbox/checkbox.class.d.ts +0 -1
  52. package/dist/components/forms/checkbox/checkbox.class.js +1 -1
  53. package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +0 -1
  54. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  55. package/dist/components/forms/code-editor/code-editor.class.js +1 -1
  56. package/dist/components/forms/color-picker/color-picker.class.js +1 -1
  57. package/dist/components/forms/combobox/combobox.class.d.ts +7 -1
  58. package/dist/components/forms/combobox/combobox.class.js +3 -2
  59. package/dist/components/forms/combobox/combobox.styles.js +1 -1
  60. package/dist/components/forms/date-picker/date-input.class.d.ts +23 -0
  61. package/dist/components/forms/date-picker/date-input.class.js +1 -1
  62. package/dist/components/forms/emoji-picker/emoji-data-loader.d.ts +0 -1
  63. package/dist/components/forms/input/native-time-input.class.js +1 -1
  64. package/dist/components/forms/input/time-input-shared.d.ts +2 -1
  65. package/dist/components/forms/input/time-input.class.js +1 -1
  66. package/dist/components/forms/locale-picker/locale-picker.class.d.ts +0 -1
  67. package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
  68. package/dist/components/forms/radio/radio-button.styles.d.ts +0 -1
  69. package/dist/components/forms/radio/radio-button.styles.js +1 -1
  70. package/dist/components/forms/radio/radio-group.class.d.ts +0 -1
  71. package/dist/components/forms/radio/radio-group.class.js +1 -1
  72. package/dist/components/forms/radio/radio.class.d.ts +0 -1
  73. package/dist/components/forms/radio/radio.class.js +1 -1
  74. package/dist/components/forms/rubric-form/rubric-form.class.d.ts +0 -1
  75. package/dist/components/forms/rubric-form/rubric-form.class.js +1 -1
  76. package/dist/components/forms/select/select.class.d.ts +0 -1
  77. package/dist/components/forms/select/select.class.js +1 -1
  78. package/dist/components/forms/slider/slider.class.d.ts +0 -1
  79. package/dist/components/forms/slider/slider.class.js +1 -1
  80. package/dist/components/forms/switch/switch.class.d.ts +0 -1
  81. package/dist/components/forms/switch/switch.class.js +1 -1
  82. package/dist/components/forms/time-range/time-range.class.d.ts +0 -1
  83. package/dist/components/forms/time-range/time-range.class.js +1 -1
  84. package/dist/components/forms/token-input/token-input.class.d.ts +0 -1
  85. package/dist/components/forms/token-input/token-input.class.js +1 -1
  86. package/dist/components/layout/app-rail/app-rail-item.class.d.ts +16 -0
  87. package/dist/components/layout/app-rail/app-rail-item.class.js +4 -4
  88. package/dist/components/layout/dashboard-grid/layout-internal.d.ts +0 -1
  89. package/dist/components/layout/dashboard-grid/layout-internal.js +1 -1
  90. package/dist/components/layout/details/accordion-owner.d.ts +1 -1
  91. package/dist/components/layout/filter-bar/filter-bar.class.d.ts +32 -3
  92. package/dist/components/layout/filter-bar/filter-bar.class.js +2 -1
  93. package/dist/components/layout/menu/menu-item.class.js +1 -1
  94. package/dist/components/layout/virtual-list/virtual-list.class.js +1 -1
  95. package/dist/components/layout/widget/widget.class.d.ts +16 -0
  96. package/dist/components/layout/widget/widget.class.js +2 -2
  97. package/dist/components/lr-funnel.d.ts +1 -0
  98. package/dist/components/lr-funnel.js +1 -0
  99. package/dist/components/media/av-player/av-metadata.d.ts +0 -2
  100. package/dist/components/media/av-player/av-metadata.js +1 -1
  101. package/dist/components/media/file-input/file-input.class.d.ts +0 -1
  102. package/dist/components/media/file-input/file-input.class.js +1 -1
  103. package/dist/components/media/flag/flag-peer-bulk-standard.d.ts +25 -0
  104. package/dist/components/media/flag/flag-peer-bulk-standard.js +1 -0
  105. package/dist/components/media/flag/flag.class.d.ts +8 -0
  106. package/dist/components/media/flag/flag.class.js +1 -1
  107. package/dist/components/media/map/map-loader.d.ts +4 -1
  108. package/dist/components/media/map/map.class.d.ts +242 -23
  109. package/dist/components/media/map/map.class.js +2 -2
  110. package/dist/components/overlays/chip/chip-group.class.d.ts +16 -0
  111. package/dist/components/overlays/chip/chip-group.class.js +10 -3
  112. package/dist/components/overlays/overlay/popover.class.d.ts +7 -1
  113. package/dist/components/overlays/overlay/popover.class.js +1 -1
  114. package/dist/components/overlays/overlay/tooltip.class.d.ts +1 -0
  115. package/dist/components/overlays/overlay/tooltip.class.js +1 -1
  116. package/dist/components/overlays/progress/progress-shared.d.ts +0 -2
  117. package/dist/components/overlays/progress/progress-shared.js +1 -1
  118. package/dist/components/overlays/rating/rating.class.js +1 -1
  119. package/dist/components/retrieval/graph/graph-canvas.d.ts +10 -9
  120. package/dist/components/retrieval/mind-map/mind-map-layout.d.ts +0 -4
  121. package/dist/components/retrieval/mind-map/mind-map-layout.js +1 -1
  122. package/dist/components/utility/format/format-options.d.ts +0 -2
  123. package/dist/components/utility/format/format-options.js +1 -1
  124. package/dist/components/utility/icon/icon-resource.d.ts +0 -2
  125. package/dist/components/utility/icon/icon-resource.js +1 -1
  126. package/dist/components/viewers/archive-viewer/zip-resource-guard.d.ts +2 -1
  127. package/dist/components/viewers/docx-viewer/docx-resource-guard.d.ts +0 -3
  128. package/dist/components/viewers/docx-viewer/docx-resource-guard.js +1 -1
  129. package/dist/components/viewers/ebook-viewer/ebook-loader.d.ts +2 -1
  130. package/dist/components/viewers/ebook-viewer/epub-resource-guard.d.ts +0 -3
  131. package/dist/components/viewers/ebook-viewer/epub-resource-guard.js +1 -1
  132. package/dist/components/viewers/pdf-viewer/pdf-loader.d.ts +2 -2
  133. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
  134. package/dist/components/viewers/pptx-viewer/pptx-resource-guard.d.ts +0 -2
  135. package/dist/components/viewers/pptx-viewer/pptx-resource-guard.js +1 -1
  136. package/dist/components/viewers/spreadsheet-viewer/xlsx-resource-guard.d.ts +0 -5
  137. package/dist/components/viewers/spreadsheet-viewer/xlsx-resource-guard.js +1 -1
  138. package/dist/custom-elements-jsx.d.ts +16 -8
  139. package/dist/events.d.ts +15 -0
  140. package/dist/internal/accessibility-visibility.d.ts +1 -1
  141. package/dist/internal/anchor-target.d.ts +1 -3
  142. package/dist/internal/anchor-target.js +2 -2
  143. package/dist/internal/anchored-overlay-runtime.d.ts +7 -0
  144. package/dist/internal/anchored-overlay-runtime.js +1 -0
  145. package/dist/internal/announcement-text.d.ts +1 -1
  146. package/dist/internal/ansi.d.ts +0 -4
  147. package/dist/internal/ansi.js +1 -1
  148. package/dist/internal/aria-ownership.d.ts +2 -1
  149. package/dist/internal/autoloader-manifest.js +1 -1
  150. package/dist/internal/autoloader-tags.d.ts +1 -1
  151. package/dist/internal/autoloader-tags.js +1 -1
  152. package/dist/internal/default-strings.generated.d.ts +1 -0
  153. package/dist/internal/default-strings.generated.js +1 -1
  154. package/dist/internal/focus-navigation.d.ts +3 -2
  155. package/dist/internal/form-associated.d.ts +0 -1
  156. package/dist/internal/form-associated.js +1 -1
  157. package/dist/internal/form-control-labels.d.ts +0 -3
  158. package/dist/internal/form-control-labels.js +1 -1
  159. package/dist/internal/localization-runtime.js +1 -1
  160. package/dist/internal/localization-types.d.ts +1 -1
  161. package/dist/internal/localization.js +1 -1
  162. package/dist/internal/lyra-element.d.ts +7 -14
  163. package/dist/internal/lyra-element.js +1 -1
  164. package/dist/internal/nonmodal-overlay-manager.d.ts +9 -0
  165. package/dist/internal/nonmodal-overlay-manager.js +1 -0
  166. package/dist/internal/overlay-manager.d.ts +4 -20
  167. package/dist/internal/overlay-manager.js +1 -1
  168. package/dist/internal/overlay-stack.d.ts +66 -0
  169. package/dist/internal/overlay-stack.js +1 -0
  170. package/dist/internal/package-metadata.d.ts +1 -1
  171. package/dist/internal/package-metadata.js +1 -1
  172. package/dist/internal/positioner.js +1 -1
  173. package/dist/internal/root-registration-allowlist.d.ts +1 -1
  174. package/dist/internal/root-registration-allowlist.js +1 -1
  175. package/dist/internal/text-quote.d.ts +1 -1
  176. package/dist/lyra.d.ts +5 -4
  177. package/dist/lyra.js +1 -1
  178. package/dist/ssr/all.d.ts +1 -0
  179. package/dist/ssr/all.js +1 -1
  180. package/dist/ssr.d.ts +4 -4
  181. package/dist/styles/tokens-root.css +488 -0
  182. package/dist/svelte.d.ts +17 -8
  183. package/dist/translations/ar.js +1 -1
  184. package/dist/translations/de.js +1 -1
  185. package/dist/translations/es.js +1 -1
  186. package/dist/translations/fa.js +1 -1
  187. package/dist/translations/fr.js +1 -1
  188. package/dist/translations/he.js +1 -1
  189. package/dist/translations/ja.js +1 -1
  190. package/dist/translations/pt-BR.js +1 -1
  191. package/dist/translations/ru.js +1 -1
  192. package/dist/translations/zh-CN.js +1 -1
  193. package/dist/utilities/localization.js +1 -1
  194. package/dist/vue.d.ts +16 -8
  195. package/llms/components/lr-app-rail-item.md +8 -1
  196. package/llms/components/lr-app-rail.md +6 -0
  197. package/llms/components/lr-chip-group.md +7 -0
  198. package/llms/components/lr-chip.md +7 -0
  199. package/llms/components/lr-combobox.md +42 -0
  200. package/llms/components/lr-date-input.md +19 -1
  201. package/llms/components/lr-date-picker.md +19 -1
  202. package/llms/components/lr-filter-bar.md +50 -1
  203. package/llms/components/lr-flag.md +14 -0
  204. package/llms/components/lr-funnel.md +122 -0
  205. package/llms/components/lr-heatmap.md +55 -8
  206. package/llms/components/lr-lite-chart.md +20 -8
  207. package/llms/components/lr-map.md +109 -22
  208. package/llms/components/lr-option.md +42 -0
  209. package/llms/components/lr-popover.md +39 -0
  210. package/llms/components/lr-table.md +7 -3
  211. package/llms/components/lr-timeline-item.md +49 -24
  212. package/llms/components/lr-timeline.md +49 -24
  213. package/llms/components/lr-widget.md +7 -1
  214. package/llms/index.md +3 -2
  215. package/llms/peers.md +1 -1
  216. package/llms/shared.md +110 -1
  217. package/llms-full.txt +681 -67
  218. package/llms.txt +1 -1
  219. package/package.json +26 -8
  220. package/vscode-css-data.json +63 -0
  221. package/vscode-html-data.json +108 -23
  222. package/web-types.json +32738 -310
@@ -961,9 +961,16 @@
961
961
  "name": "lr-app-rail-item",
962
962
  "description": {
963
963
  "kind": "markdown",
964
- "value": "`<lr-app-rail-item>` — an explicit icon/label navigation item for\n`<lr-app-rail>`. The rail sets its `icon-only` attribute as the viewport\nchanges, keeping the label available to assistive technology while removing\nit from the visual layout.\nA host `aria-label` is forwarded by attribute presence to the internal\nfocusable link or button, including an explicitly empty value.\nWhen a focused link/button is replaced, focus follows an available replacement. If the new\nowner is disabled or inert, focus returns to the available element that led into the item, or\nto the stable owning rail surface when there is no return target; a newer external focus move\nalways wins.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The visible navigation label. |\n| `icon` | The leading decorative icon. Its flattened subtree is inert and hidden from assistive technology; the default slot or host `aria-label` names the internal control. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The link or button receiving focus and activation. |\n| `icon` | The icon wrapper. |\n| `label` | The label wrapper; visually clipped in icon-only mode. |\n| `tooltip` | The hover/focus label flyout, only rendered while `tooltip` is set, the item is `icon-only`, and it is hovered or focused. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-app-rail-item-active-bg` — Pressed background; defaults to the former brand-quiet active mix.\n- `--lr-app-rail-item-active-color` (default: `var(--lr-color-brand)`) — Pressed text/icon color.\n- `--lr-app-rail-item-current-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `current`/`aria-current=\"page\"` item. Scoped to `[aria-current='page']` only and declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the current item without hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-app-rail-item-current-color` (default: `var(--lr-color-brand)`) — Text/icon color of the `current`/`aria-current=\"page\"` item.\n- `--lr-app-rail-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background.\n- `--lr-app-rail-item-hover-color` (default: `var(--lr-color-brand)`) — Hover text/icon color."
964
+ "value": "`<lr-app-rail-item>` — an explicit icon/label navigation item for\n`<lr-app-rail>`. The rail sets its `icon-only` attribute as the viewport\nchanges, keeping the label available to assistive technology while removing\nit from the visual layout.\nA host `aria-label` is forwarded by attribute presence to the internal\nfocusable link or button, including an explicitly empty value.\nWhen a focused link/button is replaced, focus follows an available replacement. If the new\nowner is disabled or inert, focus returns to the available element that led into the item, or\nto the stable owning rail surface when there is no return target; a newer external focus move\nalways wins.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n- Deprecated attribute `active`: Deprecated since `11.2.0`. Use attribute `current`. Removal is not permitted before `13.0.0`. The attribute half of the restored `active` property alias. `active` was this member's original public name in both forms; the rename to `current` was never announced, so markup that already wrote `<lr-app-rail-item active>` stopped marking the item current with no error. Shares the property record's compatibility window because it is the same correction.\n- Deprecated property `active`: Deprecated since `11.2.0`. Use property `current`. Removal is not permitted before `13.0.0`. `active` was this property's original public name and was documented as such when it shipped. It was renamed to `current` with no changelog entry, no alias and no deprecation record, so every shipped consumer's `.active=` binding silently became a dead expando -- a Lit property binding on a custom element is untyped, so nothing in a consumer's type check, test suite or build could see it. The measured downstream effect was an app rail with no current-item indicator and a permanent aria-current=\"false\". Restoring the name is a correction, not a new API, so the compatibility window runs long: this alias is what shipped consumers already wrote.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The visible navigation label. |\n| `icon` | The leading decorative icon. Its flattened subtree is inert and hidden from assistive technology; the default slot or host `aria-label` names the internal control. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The link or button receiving focus and activation. |\n| `icon` | The icon wrapper. |\n| `label` | The label wrapper; visually clipped in icon-only mode. |\n| `tooltip` | The hover/focus label flyout, only rendered while `tooltip` is set, the item is `icon-only`, and it is hovered or focused. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-app-rail-item-active-bg` — Pressed background; defaults to the former brand-quiet active mix.\n- `--lr-app-rail-item-active-color` (default: `var(--lr-color-brand)`) — Pressed text/icon color.\n- `--lr-app-rail-item-current-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `current`/`aria-current=\"page\"` item. Scoped to `[aria-current='page']` only and declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the current item without hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-app-rail-item-current-color` (default: `var(--lr-color-brand)`) — Text/icon color of the `current`/`aria-current=\"page\"` item.\n- `--lr-app-rail-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background.\n- `--lr-app-rail-item-hover-color` (default: `var(--lr-color-brand)`) — Hover text/icon color."
965
965
  },
966
966
  "attributes": [
967
+ {
968
+ "name": "active",
969
+ "description": {
970
+ "kind": "markdown",
971
+ "value": "Deprecated alias for `current`, read alongside it.\n\n`active` was this property's original public name. It was renamed to `current` with no\nchangelog entry, no alias and no deprecation record, which broke every shipped consumer\nsilently: a Lit `.active=${...}` binding on a custom element is untyped, so it did not error --\nit became a dead expando, leaving the rail with no current-item indicator and a permanent\n`aria-current=\"false\"`. Nothing in a consumer's type check, test suite or build could see that.\n\nSet either name; the item is current when either is true. Prefer `current`.\n\nDeprecated since `11.2.0`. Use attribute `current`. Removal is not permitted before `13.0.0`. The attribute half of the restored `active` property alias. `active` was this member's original public name in both forms; the rename to `current` was never announced, so markup that already wrote `<lr-app-rail-item active>` stopped marking the item current with no error. Shares the property record's compatibility window because it is the same correction.\n\nType: `boolean` \nDefault: `false`"
972
+ }
973
+ },
967
974
  {
968
975
  "name": "current",
969
976
  "description": {
@@ -1987,7 +1994,7 @@
1987
1994
  "name": "description",
1988
1995
  "description": {
1989
1996
  "kind": "markdown",
1990
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
1997
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
1991
1998
  }
1992
1999
  },
1993
2000
  {
@@ -2540,7 +2547,7 @@
2540
2547
  "name": "description",
2541
2548
  "description": {
2542
2549
  "kind": "markdown",
2543
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
2550
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
2544
2551
  }
2545
2552
  },
2546
2553
  {
@@ -3741,7 +3748,7 @@
3741
3748
  "name": "description",
3742
3749
  "description": {
3743
3750
  "kind": "markdown",
3744
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
3751
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
3745
3752
  }
3746
3753
  },
3747
3754
  {
@@ -4823,9 +4830,16 @@
4823
4830
  "name": "lr-chip-group",
4824
4831
  "description": {
4825
4832
  "kind": "markdown",
4826
- "value": "`<lr-chip-group>` — a flex-wrap container for a set of `<lr-chip>`\nchildren (plain light-DOM composition — direct children are the chips,\nthe same shape `<lr-multi-split>`'s panels / `<lr-source-list>`'s cards\ntake — no `.items` array prop).\n\n`max-visible` is entirely optional. When unset, every child is always\nshown and this component does nothing beyond flex-wrap layout. When set\nand the group has more chip children than that, the excess children are\nhidden (via their own `hidden` property — CSS alone can't parameterize\n`:nth-child` on a runtime prop, so this reaches into the light DOM the\nsame way `<lr-multi-split>` sets each panel's inline `flex`/`order`) and a\n\"+N\" overflow-indicator pill takes their place. Clicking it is a toggle:\nit reveals the rest (and relabels itself \"Show less\"); clicking again\nre-collapses back to `max-visible`. `lr-overflow-toggle` fires only from\nthat click — i.e. only when `max-visible` is actually causing an overflow\nstate — never as a side effect of `max-visible`/children changing on\ntheir own.\n\nAuthor-owned `hidden` changes remain live while collapse management is active. The latest author\nstate is restored when a child leaves or the group disconnects, and reconnecting reapplies the\ncurrent collapsed state.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | `<lr-chip>` elements (or any content, though the chip pairing is the intended usage). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The flex-wrap container (holds both the slot and the overflow indicator). |\n| `overflow-indicator` | The \"+N\" / \"Show less\" toggle button. Only rendered while `max-visible` is actively causing an overflow. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chip-group-overflow-expanded-border-style` (default: `solid`) — Border style of `[part=\"overflow-indicator\"]` while expanded. The resting indicator intentionally stays dashed, so this can retune the expanded state without losing that structural affordance.\n- `--lr-chip-group-overflow-expanded-color` (default: `var(--lr-color-text)`) — Text color of `[part=\"overflow-indicator\"]` while expanded (`aria-expanded=\"true\"`). `::part(overflow-indicator)[aria-expanded='true']` is invalid CSS, so this is the only way to retint the expanded state without re-pointing the shared `--lr-color-text` token."
4833
+ "value": "`<lr-chip-group>` — a flex-wrap container for a set of `<lr-chip>`\nchildren (plain light-DOM composition — direct children are the chips,\nthe same shape `<lr-multi-split>`'s panels / `<lr-source-list>`'s cards\ntake — no `.items` array prop).\n\n`max-visible` is entirely optional. When unset, every child is always\nshown and this component does nothing beyond flex-wrap layout. When set\nand the group has more chip children than that, the excess children are\nhidden (via their own `hidden` property — CSS alone can't parameterize\n`:nth-child` on a runtime prop, so this reaches into the light DOM the\nsame way `<lr-multi-split>` sets each panel's inline `flex`/`order`) and a\n\"+N\" overflow-indicator pill takes their place. Clicking it is a toggle:\nit reveals the rest (and relabels itself \"Show less\"); clicking again\nre-collapses back to `max-visible`. `lr-overflow-toggle` fires only from\nthat click — i.e. only when `max-visible` is actually causing an overflow\nstate — never as a side effect of `max-visible`/children changing on\ntheir own.\n\nAuthor-owned `hidden` changes remain live while collapse management is active. The latest author\nstate is restored when a child leaves or the group disconnects, and reconnecting reapplies the\ncurrent collapsed state.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | `<lr-chip>` elements (or any content, though the chip pairing is the intended usage). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The flex-wrap container (holds both the slot and the overflow indicator). Carries `role=\"group\"` and the accessible name when one is supplied -- see `accessibleLabel`. |\n| `overflow-indicator` | The \"+N\" / \"Show less\" toggle button. Only rendered while `max-visible` is actively causing an overflow. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chip-group-overflow-expanded-border-style` (default: `solid`) — Border style of `[part=\"overflow-indicator\"]` while expanded. The resting indicator intentionally stays dashed, so this can retune the expanded state without losing that structural affordance.\n- `--lr-chip-group-overflow-expanded-color` (default: `var(--lr-color-text)`) — Text color of `[part=\"overflow-indicator\"]` while expanded (`aria-expanded=\"true\"`). `::part(overflow-indicator)[aria-expanded='true']` is invalid CSS, so this is the only way to retint the expanded state without re-pointing the shared `--lr-color-text` token."
4827
4834
  },
4828
4835
  "attributes": [
4836
+ {
4837
+ "name": "aria-label",
4838
+ "description": {
4839
+ "kind": "markdown",
4840
+ "value": "Accessible name for the group, forwarded to `[part=\"base\"]`.\n\nA chip group IS a group, and every peer grouping primitive here already says so --\n`<lr-radio-group>` renders `role=\"radiogroup\"`, `<lr-segmented>` the same, each forwarding a\nhost `aria-label` inward. This component rendered a roleless container and read no name, and\nbecause a host `aria-label` does not cross a shadow boundary, a consumer labelling the host\nnamed nothing at all. Supplying a name here (as the `aria-label` attribute or this property)\nis what makes the group real to assistive technology.\n\nThe `role=\"group\"` is applied only WITH a name, deliberately: an unnamed group role adds\nverbosity without adding information, and applying it unconditionally would change the\naccessibility tree of every decorative chip row already shipped.\n\nType: `string` \nDefault: `''`"
4841
+ }
4842
+ },
4829
4843
  {
4830
4844
  "name": "locale",
4831
4845
  "description": {
@@ -8785,7 +8799,7 @@
8785
8799
  "name": "description",
8786
8800
  "description": {
8787
8801
  "kind": "markdown",
8788
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
8802
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
8789
8803
  }
8790
8804
  },
8791
8805
  {
@@ -10608,7 +10622,7 @@
10608
10622
  "name": "lr-filter-bar",
10609
10623
  "description": {
10610
10624
  "kind": "markdown",
10611
- "value": "`<lr-filter-bar>` — a row of dashboard filters, each declared by the host (`filters`) rather\nthan invented by this component: every filter composes an existing Lyra input --\n`<lr-select>`/`<lr-combobox>` for closed choice sets, `<lr-date-input>` (single or `mode=\"range\"`)\nfor dates, `<lr-input>` for a free-text query -- plus a `<lr-chip-group>` of removable\n`<lr-chip>`s summarizing the currently-active filters, an `<lr-button>` that resets every\nfilter, and (while `loading`) an `<lr-spinner>` status indicator.\n\nA `'text'` filter is the one control that is *not* a fully controlled `.value=` binding: a text\nfield re-rendered from `value` mid-typing would push a stale value back into the field and drop\nthe caret to the end, so the field owns its own value while the user types and an external\n`value` write is synced back in only once no edit is in flight (see `syncTextControls()`). Its\noptional per-filter `debounce` (ms) is the only behaviour this component adds on top of the\ncomposed control itself -- flushed by that field's own `change`/blur, cancelled by `reset()`, a\nchip removal, and `disconnectedCallback`, so a stale keystroke can never overwrite a reset or\nfire after teardown.\n\nControlled, like every other Lyra data component: `value` is a plain, JSON-serializable object\n(`LyraFilterBarValue`) the host reads/writes directly -- this component never touches\n`location`/`history`/storage itself, so turning `value` into (and back out of) a URL\nquerystring or an app state store is entirely the host's own concern. Every edit -- picking an\noption, committing a date, removing an active-filter chip, or clicking reset -- goes through\nthe same `setFilterValue()` path and emits a single `lr-input` carrying the *full* resulting\n`value`, not just the changed filter's own value, mirroring `<lr-tool-param-form>`'s identical\n\"always the whole object\" event contract. A composed control's own `lr-input`/`lr-change`\naliases stay inside this wrapper; its native-style `input`/`change` events retain their normal\nbubbling path. Date/date-range chip labels localize only\nround-trip-valid ISO `YYYY-MM-DD` segments, including literal four-digit years `0000`-`0099`.\nImpossible dates, malformed values, and a range with either invalid endpoint remain verbatim so\ndisplay never invents a normalized day.\n\nValidation is scoped to each filter definition's own `required` flag: `invalidFilterIds`/\n`checkValidity()` are always live (plain getters over `filters`/`value`, not cached), and\n`reportValidity()` additionally reveals every currently-invalid filter's inline error (rendered\nby that filter's own composed control, via its `errorText`/`required` props -- this component\nnever renders a second, duplicate label/hint/error chrome of its own around an already-chromed\ncontrol) the same way a blur naturally would. `lr-validity-change` fires whenever the computed\n`{ valid, invalidFilterIds }` actually changes.\n\nDeliberately not form-associated: a dashboard filter bar's state is not a submitted form field,\nand every value it holds already round-trips through `value` directly -- see `disabled` below,\na plain property with no `<fieldset disabled>` cascade, for the same reason.\n\nThe composed reset action stays on `lr-button`'s default `m` size tier, matching the default\nselect/combobox/input/date field height beside it instead of introducing a shorter action row.\nThe active-filter row and its composed chip group also zero every nested flex auto minimum, so\nan unbroken localized value stays inside a narrow allocation and the chip's own label ellipsis\nremains the overflow owner in both writing directions.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.1.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `active-filters` | The `role=\"group\"` wrapper around the active-filter chip row, only rendered while any filter is set. |\n| `base` | The root `role=\"group\"` wrapper. |\n| `chip` | One active-filter `<lr-chip>`. |\n| `chips` | The `<lr-chip-group>` inside `active-filters`. |\n| `controls` | The row holding every filter control, the reset button, and the loading status. |\n| `filter-control` | One filter's composed built-in control, or the wrapper around a custom renderer's control. |\n| `filter-control-clear-button` | A built-in control's clear action, when rendered. |\n| `filter-control-end` | A built-in control's end adornment wrapper. |\n| `filter-control-error` | A built-in control's validation message. |\n| `filter-control-expand-button` | A date input's calendar-popup action. |\n| `filter-control-expand-icon` | A select, combobox, or date-input expansion icon. |\n| `filter-control-field` | A built-in control's field frame: select trigger, combobox container, or text/date input wrapper. |\n| `filter-control-hint` | A built-in control's hint message. |\n| `filter-control-input` | A built-in control's display or editable input. |\n| `filter-control-label` | A built-in control's label element. |\n| `filter-control-listbox` | A select or combobox options popover. |\n| `filter-control-option` | A select or combobox option row. |\n| `filter-control-popup` | A date input's positioned calendar popup. |\n| `filter-control-start` | A built-in control's start adornment wrapper. |\n| `reset-button` | The reset `<lr-button>`. |\n| `status` | The loading `<lr-spinner>`, only rendered while `loading`. |"
10625
+ "value": "`<lr-filter-bar>` — a row of dashboard filters, each declared by the host (`filters`) rather\nthan invented by this component: every filter composes an existing Lyra input --\n`<lr-select>`/`<lr-combobox>` for closed choice sets, `<lr-date-input>` (single or `mode=\"range\"`)\nfor dates, `<lr-input>` for a free-text query -- plus a `<lr-chip-group>` of removable\n`<lr-chip>`s summarizing the currently-active filters, an `<lr-button>` that resets every\nfilter, and (while `loading`) an `<lr-spinner>` status indicator.\n\nA `'text'` filter is the one control that is *not* a fully controlled `.value=` binding: a text\nfield re-rendered from `value` mid-typing would push a stale value back into the field and drop\nthe caret to the end, so the field owns its own value while the user types and an external\n`value` write is synced back in only once no edit is in flight (see `syncTextControls()`). Its\noptional per-filter `debounce` (ms) is the only behaviour this component adds on top of the\ncomposed control itself -- flushed by that field's own `change`/blur, cancelled by `reset()`, a\nchip removal, and `disconnectedCallback`, so a stale keystroke can never overwrite a reset or\nfire after teardown.\n\nControlled, like every other Lyra data component: `value` is a plain, JSON-serializable object\n(`LyraFilterBarValue`) the host reads/writes directly -- this component never touches\n`location`/`history`/storage itself, so turning `value` into (and back out of) a URL\nquerystring or an app state store is entirely the host's own concern. Every edit -- picking an\noption, committing a date, removing an active-filter chip, or clicking reset -- goes through\nthe same `setFilterValue()` path and emits a single `lr-input` carrying the *full* resulting\n`value`, not just the changed filter's own value, mirroring `<lr-tool-param-form>`'s identical\n\"always the whole object\" event contract. A composed control's own `lr-input`/`lr-change`\naliases stay inside this wrapper; its native-style `input`/`change` events retain their normal\nbubbling path. Date/date-range chip labels localize only\nround-trip-valid ISO `YYYY-MM-DD` segments, including literal four-digit years `0000`-`0099`.\nImpossible dates, malformed values, and a range with either invalid endpoint remain verbatim so\ndisplay never invents a normalized day. A `'date-range'` filter may also declare `presets`,\nforwarded to its composed `<lr-date-input>` exactly like `min`/`max`; the entry that produced a\ncommit rides that edit's own `lr-input` as `appliedPreset`, so a bar whose values round-trip\nthrough a query string can persist which range is active rather than the pair it froze to.\n\nValidation is scoped to each filter definition's own `required` flag: `invalidFilterIds`/\n`checkValidity()` are always live (plain getters over `filters`/`value`, not cached), and\n`reportValidity()` additionally reveals every currently-invalid filter's inline error (rendered\nby that filter's own composed control, via its `errorText`/`required` props -- this component\nnever renders a second, duplicate label/hint/error chrome of its own around an already-chromed\ncontrol) the same way a blur naturally would. `lr-validity-change` fires whenever the computed\n`{ valid, invalidFilterIds }` actually changes.\n\nDeliberately not form-associated: a dashboard filter bar's state is not a submitted form field,\nand every value it holds already round-trips through `value` directly -- see `disabled` below,\na plain property with no `<fieldset disabled>` cascade, for the same reason.\n\nThe composed reset action stays on `lr-button`'s default `m` size tier, matching the default\nselect/combobox/input/date field height beside it instead of introducing a shorter action row.\nThe active-filter row and its composed chip group also zero every nested flex auto minimum, so\nan unbroken localized value stays inside a narrow allocation and the chip's own label ellipsis\nremains the overflow owner in both writing directions.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.1.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `active-filters` | The `role=\"group\"` wrapper around the active-filter chip row, only rendered while any filter is set. |\n| `base` | The root `role=\"group\"` wrapper. |\n| `chip` | One active-filter `<lr-chip>`. |\n| `chips` | The `<lr-chip-group>` inside `active-filters`. |\n| `controls` | The row holding every filter control, the reset button, and the loading status. |\n| `filter-control` | One filter's composed built-in control, or the wrapper around a custom renderer's control. |\n| `filter-control-clear-button` | A built-in control's clear action, when rendered. |\n| `filter-control-end` | A built-in control's end adornment wrapper. |\n| `filter-control-error` | A built-in control's validation message. |\n| `filter-control-expand-button` | A date input's calendar-popup action. |\n| `filter-control-expand-icon` | A select, combobox, or date-input expansion icon. |\n| `filter-control-field` | A built-in control's field frame: select trigger, combobox container, or text/date input wrapper. |\n| `filter-control-hint` | A built-in control's hint message. |\n| `filter-control-input` | A built-in control's display or editable input. |\n| `filter-control-label` | A built-in control's label element. |\n| `filter-control-listbox` | A select or combobox options popover. |\n| `filter-control-option` | A select or combobox option row. |\n| `filter-control-popup` | A date input's positioned calendar popup. |\n| `filter-control-start` | A built-in control's start adornment wrapper. |\n| `reset-button` | The reset `<lr-button>`. |\n| `status` | The loading `<lr-spinner>`, only rendered while `loading`. |"
10612
10626
  },
10613
10627
  "attributes": [
10614
10628
  {
@@ -10645,7 +10659,7 @@
10645
10659
  "name": "lr-flag",
10646
10660
  "description": {
10647
10661
  "kind": "markdown",
10648
- "value": "`<lr-flag>` — a country/language flag.\n\nFlag images are shipped by the optional peer package `@aceshooting/lyra-flags`,\nnot bundled into lyra-ui itself, so importing the core library pulls zero flag\nweight. Give it a `country` (ISO 3166-1 alpha-2) or a `language` tag (mapped to\na representative country). While that peer package's `flagUrl()` resolves,\nthe host carries `aria-busy=\"true\"`; a decorative skeleton and ordinary, non-live localized\nloading text render in its place. A missing or failed peer resolver fails closed with a localized visible error and a\nshared light-DOM assertive announcement, plus a one-time `console.warn` naming the code and the\n`flag-peer.js` import that registers a resolver -- the visible error alone cannot tell a\ndeveloper that the fix is a missing import rather than missing flag data;\nan installed resolver returning no URL for an unknown code remains a valid\nempty result.\n\n**Bundle-size note:** `country`/`language` resolve through the peer package's\n`flagUrl(code)`, which lazily fetches one requested flag at runtime. A\nbundler may still emit the complete reachable lazy-chunk graph; use a\nliteral asset subpath import when the deployment artifact must be pruned.\nIf every `<lr-flag>` in your app is pinned to the same `fidelity` (no\nper-instance switching), register `@aceshooting/lyra-flags/standard`/`/compact`/`/detailed` with\n`setFlagUrlResolver()` instead of importing `flag-peer.js` (which always registers the full\nthree-tier resolver) — the tier-specific entry excludes the other two tiers' generated loader\nmaps from the reachable graph; see that package's README for the exact shape.\nIf you already\nhave a flag's URL at build time (e.g. from your own literal\n`import frUrl from '@aceshooting/lyra-flags/flags/fr.svg?url'`), pass it as\n`src` instead to skip the peer-package round trip (and its loading-skeleton\nflash) entirely.\n\n**Rendering many flags at once** (a country table, a picker listing every locale): resolve every\ncode up front with `@aceshooting/lyra-flags`'s `flagUrls()` (one call, returns `{code: url}` for\nall 249 flags) and pass results through `src`, instead of letting each `<lr-flag>` instance\nindependently call `flagUrl()` — this skips one peer-resolution round trip per instance. Image\nfetches themselves are unaffected either way (each flag is a distinct asset; there is no sprite).\nOr import `flag-peer-bulk.js` instead of `flag-peer.js` (never both) to get this automatically,\nregistering a resolver backed by one shared `flagUrls()` call — worthwhile only when the page\nrenders most/all flags; a page with a handful pays an unneeded 249-entry fetch.\n\n**Sizing:** the host has no intrinsic `width` — it sizes from `font-size` (`block-size: 1em`,\n`inline-size` derived from `--lr-flag-aspect-ratio` via CSS `aspect-ratio`), so `<lr-flag>` scales\nnaturally with surrounding text (e.g. `style=\"font-size: 2rem\"`). Do not set `width`/`inline-size`\ndirectly: making both axes definite defeats `aspect-ratio` (which only participates when at most\none axis is definite per the CSS sizing spec), squashing the image instead of scaling it.\n\nThe ~65 flags whose design includes a detailed coat of arms/seal/emblem (e.g. `es`, `pt`) ship\nthree fidelity tiers; choose one with `fidelity`: `\"compact\"` (a tiny WebP raster for icon-scale\nuse — menu items, language selectors, dense lists), the default `\"standard\"` (icon-optimized\nvector for card/row sizes), or `\"detailed\"` (the pristine full-detail vector for hero-scale\ndisplay). A no-op for every other code — all tiers resolve to the same file. See `fidelity`'s own\ndoc.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `fallback` | Rendered in place of the flag when `country`/`language` cannot resolve to a current flag (an unassigned, historical, or malformed code). Wins over the `fallback` property. Distinct from the peer-resolver failure that produces `[part=\"error\"]`: an unresolvable code is data, not a defect. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `error` | Ordinary localized visible error rendered when the optional peer resolver is unavailable or fails; each fresh resolution failure appends the same localized message to the shared light-DOM assertive announcement sink. |\n| `fallback-image` | The `fallback` property's placeholder image, when no `fallback` slot content is supplied. |\n| `image` | The underlying <img>. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-flag-aspect-ratio` (default: `4 / 3`) — Rectangular flag aspect ratio.\n- `--lr-flag-object-fit` (default: `cover`) — How the image fits its flag frame.\n- `--lr-flag-radius` — Rectangular flag corner radius."
10662
+ "value": "`<lr-flag>` — a country/language flag.\n\nFlag images are shipped by the optional peer package `@aceshooting/lyra-flags`,\nnot bundled into lyra-ui itself, so importing the core library pulls zero flag\nweight. Give it a `country` (ISO 3166-1 alpha-2) or a `language` tag (mapped to\na representative country). While that peer package's `flagUrl()` resolves,\nthe host carries `aria-busy=\"true\"`; a decorative skeleton and ordinary, non-live localized\nloading text render in its place. A missing or failed peer resolver fails closed with a localized visible error and a\nshared light-DOM assertive announcement, plus a one-time `console.warn` naming the code and the\n`flag-peer.js` import that registers a resolver -- the visible error alone cannot tell a\ndeveloper that the fix is a missing import rather than missing flag data;\nan installed resolver returning no URL for an unknown code remains a valid\nempty result.\n\n**Bundle-size note:** `country`/`language` resolve through the peer package's\n`flagUrl(code)`, which lazily fetches one requested flag at runtime. A\nbundler may still emit the complete reachable lazy-chunk graph; use a\nliteral asset subpath import when the deployment artifact must be pruned.\nIf every `<lr-flag>` in your app is pinned to the same `fidelity` (no\nper-instance switching), register `@aceshooting/lyra-flags/standard`/`/compact`/`/detailed` with\n`setFlagUrlResolver()` instead of importing `flag-peer.js` (which always registers the full\nthree-tier resolver) — the tier-specific entry excludes the other two tiers' generated loader\nmaps from the reachable graph; see that package's README for the exact shape.\nIf you already\nhave a flag's URL at build time (e.g. from your own literal\n`import frUrl from '@aceshooting/lyra-flags/flags/fr.svg?url'`), pass it as\n`src` instead to skip the peer-package round trip (and its loading-skeleton\nflash) entirely.\n\n**Rendering many flags at once** (a country table, a picker listing every locale): resolve every\ncode up front with `@aceshooting/lyra-flags`'s `flagUrls()` (one call, returns `{code: url}` for\nall 249 flags) and pass results through `src`, instead of letting each `<lr-flag>` instance\nindependently call `flagUrl()` — this skips one peer-resolution round trip per instance. Image\nfetches themselves are unaffected either way (each flag is a distinct asset; there is no sprite).\nOr import `flag-peer-bulk.js` instead of `flag-peer.js` (never both) to get this automatically,\nregistering a resolver backed by one shared `flagUrls()` call — worthwhile only when the page\nrenders most/all flags; a page with a handful pays an unneeded 249-entry fetch.\nWhen that page ALSO leaves every `<lr-flag>` on the default `fidelity=\"standard\"`, import\n`flag-peer-bulk-standard.js` instead: it registers the same bulk resolver through the peer\npackage's tier-committed `@aceshooting/lyra-flags/standard` entry, so the detailed and compact\ntiers' lazy-chunk graphs never become reachable (measured at +15.8MB of emitted assets on a real\nproduction build with a 156-country flag column). It is committed to one tier, so\n`fidelity=\"compact\"/\"detailed\"` on an individual element resolves to that code's standard asset\n— a silent no-op, not an error; use `flag-peer-bulk.js` when per-instance fidelity must be\nhonoured.\n\n**Sizing:** the host has no intrinsic `width` — it sizes from `font-size` (`block-size: 1em`,\n`inline-size` derived from `--lr-flag-aspect-ratio` via CSS `aspect-ratio`), so `<lr-flag>` scales\nnaturally with surrounding text (e.g. `style=\"font-size: 2rem\"`). Do not set `width`/`inline-size`\ndirectly: making both axes definite defeats `aspect-ratio` (which only participates when at most\none axis is definite per the CSS sizing spec), squashing the image instead of scaling it.\n\nThe ~65 flags whose design includes a detailed coat of arms/seal/emblem (e.g. `es`, `pt`) ship\nthree fidelity tiers; choose one with `fidelity`: `\"compact\"` (a tiny WebP raster for icon-scale\nuse — menu items, language selectors, dense lists), the default `\"standard\"` (icon-optimized\nvector for card/row sizes), or `\"detailed\"` (the pristine full-detail vector for hero-scale\ndisplay). A no-op for every other code — all tiers resolve to the same file. See `fidelity`'s own\ndoc.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `fallback` | Rendered in place of the flag when `country`/`language` cannot resolve to a current flag (an unassigned, historical, or malformed code). Wins over the `fallback` property. Distinct from the peer-resolver failure that produces `[part=\"error\"]`: an unresolvable code is data, not a defect. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `error` | Ordinary localized visible error rendered when the optional peer resolver is unavailable or fails; each fresh resolution failure appends the same localized message to the shared light-DOM assertive announcement sink. |\n| `fallback-image` | The `fallback` property's placeholder image, when no `fallback` slot content is supplied. |\n| `image` | The underlying <img>. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-flag-aspect-ratio` (default: `4 / 3`) — Rectangular flag aspect ratio.\n- `--lr-flag-object-fit` (default: `cover`) — How the image fits its flag frame.\n- `--lr-flag-radius` — Rectangular flag corner radius."
10649
10663
  },
10650
10664
  "attributes": [
10651
10665
  {
@@ -11528,6 +11542,50 @@
11528
11542
  }
11529
11543
  ]
11530
11544
  },
11545
+ {
11546
+ "name": "lr-funnel",
11547
+ "description": {
11548
+ "kind": "markdown",
11549
+ "value": "`<lr-funnel>` — a dependency-free conversion funnel: an ordered set of stages, each drawn as a\nbar whose length is that stage's share of the FIRST stage, read top-to-bottom as progressive\ndrop-off.\n\nThis is an analytics primitive rather than a general chart type — a sibling of `<lr-gauge>` and\n`<lr-heatmap>` rather than of the Chart.js-backed chart family, and it pulls no charting peer.\nIt renders plain HTML, so stage names, absolute values, shares and drop-off percentages are real\ntext in the DOM rather than a sighted-only drawing with a separate transcript bolted on.\n\nA funnel is deliberately not a sorted bar chart: it normalizes to the first stage instead of the\ndata maximum, draws no value axis, and reads as stage-to-stage retention rather than category\ncomparison.\n\nDegenerate inputs are defined rather than avoided:\n\n- An empty series renders the localized empty state and no list.\n- A single stage renders one full-length bar and no drop-off row.\n- A zero or negative first stage cannot define a share, so shares and drop-off percentages are\n omitted, every bar is zero-length, and the absolute values still render.\n- A stage larger than its predecessor (funnel re-entry) reports its true share above 100% in\n text while its bar clamps to the track, carrying the extra bar-overflow part token.\n- A comparison series of a different length pairs by index: extra comparison entries are\n ignored, and stages past its end simply get no comparison bar.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `12.0.0`\n- Rationale: This newly scaffolded component is an unreleased public-surface candidate whose API is still under maintainer review.\n- Graduation: Graduate to stable only after its documented API, populated accessibility state, three-engine behavior, and compatibility contract pass review and a release qualification.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `bar` | A stage's bar. |\n| `bar-overflow` | Added to bar when the stage exceeds the first stage. |\n| `base` | The container element. |\n| `comparison-bar` | The comparison series' outline drawn behind a stage's bar. |\n| `comparison-value` | The comparison series' share for a stage. |\n| `dropoff` | The change from the previous stage, above each stage after the first. |\n| `empty` | The empty state shown when there are no stages. |\n| `stage` | One stage row. |\n| `stage-header` | The text row above a stage's bar. |\n| `stage-label` | A stage's name. |\n| `stage-share` | A stage's share of the first stage. |\n| `stage-value` | A stage's absolute value. |\n| `stages` | The ordered list of stages. |\n| `track` | The full-length groove a stage's bar is drawn in. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-funnel-bar-color` (default: `var(--lr-color-brand)`) — Fill of every stage bar that has no own color.\n- `--lr-funnel-bar-size` (default: `var(--lr-size-1-5rem)`) — Thickness of a stage's track.\n- `--lr-funnel-comparison-color` (default: `var(--lr-color-border-strong)`) — Outline of the comparison bars.\n- `--lr-funnel-track-color` (default: `var(--lr-color-surface-raised)`) — Background of the bar track."
11550
+ },
11551
+ "attributes": [
11552
+ {
11553
+ "name": "comparison-label",
11554
+ "description": {
11555
+ "kind": "markdown",
11556
+ "value": "Name for the comparison series. Falls back to a localized generic label.\n\nType: `string` \nDefault: `''`"
11557
+ }
11558
+ },
11559
+ {
11560
+ "name": "dropoff",
11561
+ "description": {
11562
+ "kind": "markdown",
11563
+ "value": "Whether the change from the previous stage is rendered above each later stage.\n\nType: `boolean` \nDefault: `true`"
11564
+ }
11565
+ },
11566
+ {
11567
+ "name": "label",
11568
+ "description": {
11569
+ "kind": "markdown",
11570
+ "value": "Accessible name for the stage list. A host `aria-label` wins over it.\n\nType: `string` \nDefault: `''`"
11571
+ }
11572
+ },
11573
+ {
11574
+ "name": "locale",
11575
+ "description": {
11576
+ "kind": "markdown",
11577
+ "value": "Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string` \nDefault: `''`"
11578
+ }
11579
+ },
11580
+ {
11581
+ "name": "share-precision",
11582
+ "description": {
11583
+ "kind": "markdown",
11584
+ "value": "Fraction digits used for every share and drop-off percentage.\n\nType: `number` \nDefault: `0`"
11585
+ }
11586
+ }
11587
+ ]
11588
+ },
11531
11589
  {
11532
11590
  "name": "lr-gauge",
11533
11591
  "description": {
@@ -12077,7 +12135,7 @@
12077
12135
  "name": "lr-heatmap",
12078
12136
  "description": {
12079
12137
  "kind": "markdown",
12080
- "value": "`<lr-heatmap>` — a Canvas heatmap with a DPR-aware, resize-aware redraw\nloop. Its discriminated `data` property selects one of two projections:\n\n- `{ kind: \"matrix\", rowLabels, colLabels, values }` (default): a labeled matrix. `-1`\n (or any non-finite value) is treated as \"no data\". `scale=\"sqrt\"`\n compresses the ramp via `sqrtStep()` so one heavy cell doesn't wash out\n the rest; the default `\"linear\"` scale maps linearly instead.\n- `{ kind: \"calendar\", days, firstDayOfWeek?, columnX?, rowY?, ... }`: a GitHub-style\n weekday x week grid. `scale` governs its\n bucketing too: the default `\"linear\"` buckets by `quartileBucket()`\n (today's original behavior, unchanged); `\"sqrt\"` instead compresses via\n the same `sqrtStep()` magnitude compression matrix mode uses, so one\n heavy day doesn't wash out the rest. As in matrix mode, a cell whose\n `value` is negative or non-finite is treated as \"no data\" rather than\n being bucketed — as is a grid position with no matching entry in `days`\n at all (a gap in a sparse calendar).\n\n`fitToWidth` divides the host's measured width across the grid in either\nmode; `maxCellSize`/`minCellSize` bound the result, so a sparse grid in a\nwide pane cannot inflate into a few giant blocks and a year calendar in a\nnarrow one cannot collapse into hairlines. Both are ignored while\n`fitToWidth` is unset (an explicit `cellSize` is an exact request), and the\ncanvas is sized from the *clamped* size — a capped grid leaves the host's\nremaining width unfilled rather than stretching to it.\n\nThe sequential color ramp's endpoints are read from the\n`--lr-heatmap-scale-lo`/`-hi` custom properties (declared in\n`heatmap.styles.ts`) so hosts can retheme it — canvas can't consume\n`var()` directly, so they're resolved once per draw via\n`getComputedStyle`, then normalized to RGB by `resolveRgb()` (any valid\nCSS color syntax, not just hex — see its doc comment).\n\nEvery cell is independently addressable: a `pointermove` hit test over the\ncanvas shows `[part=\"tooltip\"]` with that cell's label + value (hidden on\n`pointerleave`); the canvas is a named `role=\"application\"`, `tabindex=\"0\"` control with\narrow-key roving focus (a stroked ring redrawn over the focused cell on every draw, plus a\nshared light-DOM polite status announcement — avoids a\nDOM-node-per-cell overlay, which would be hundreds of nodes for a year\ncalendar); and a click, or Enter/Space on the focused cell, fires\n`lr-cell-click`. `annotations` additionally strokes a ring around\nspecific cells (e.g. to call out an anomaly), each one optionally\nsurfaced in the legend too via `[part=\"legend-annotation\"]`.\n\nBoth grid modes deliberately retain physical LTR geometry under `dir=\"rtl\"`:\nmatrix column 0 and calendar week 0 remain at the physical left. ArrowLeft\nand ArrowRight therefore retain their physical previous/next movement rather\nthan swapping under RTL, matching the grid the user sees.\n\nIn calendar mode every cell position handed to `cellText`, `cellColor` and\n`cellInteractive` is a `CalendarCellPos` carrying the resolved ISO\n`yyyy-mm-dd` `date` alongside `week`/`weekday` — including for a grid\nposition with no entry in `days` at all — so a callback can key off the\ndate without re-deriving the grid's own anchor arithmetic.\n\n`legendStops` swaps the legend's two-endpoint gradient bar for a discrete\nkey of swatches, so a consumer whose `cellColor` callback paints an\nentirely different domain than the `--lr-heatmap-scale-lo`/`-hi` ramp can\nkeep the built-in legend (labels, number formatting, annotation entries)\ninstead of hiding `[part=\"legend\"]` and hand-rolling swatches. It is\npresentation only — it never feeds back into the cell colors.\n\nSet `accessibleCells` when cells need persistent DOM semantics for\nassistive technology. The opt-in semantic grid virtualizes native buttons to a bounded\nwindow while retaining full row/column counts, complete arrow navigation,\nlocalized `aria-label`, and explicit `aria-selected` state\nderived from the controlled `selectedCell` property; the canvas remains the\nvisual rendering surface underneath. When grid data refreshes while one of those buttons owns\nfocus, its semantic matrix coordinate or calendar date remains the sole roving stop; removal\nclamps to the nearest survivor, or to the stable heatmap base when no interactive cells remain.\n\nCalendar `data.columnX` overrides the x-origin computed for each\nweek column — drawing, hit-testing, the focus ring, and month-label\npositioning all consult it consistently, so a consumer can pixel-align a\ncalendar's week columns with a sibling chart's coordinate system. Unset\n(the default) keeps the original evenly-spaced formula. `data.rowY` is its\ncalendar-mode vertical analogue — overrides the y-origin computed for each\nweekday row, consulted consistently by drawing, hit-testing, and the focus\nring via the private `rowYFor()` helper (mirroring `columnXFor()` exactly).\n\n`data.firstDayOfWeek` (calendar only, default `0`/Sunday)\nanchors the calendar grid at a different weekday — `0`-`6`, same\nnumbering as `CalendarCellPos.weekday` (`0` Sunday .. `6` Saturday) —\nthreaded into `buildCalendarGrid()`.\n\n`cellSize`/`fitToWidth` (previously matrix-mode only) also drive calendar\nmode's per-cell size: unset, calendar mode keeps today's original 11px\ncell size unchanged; explicitly set, the same fixed size (or, with\n`fitToWidth`, the same host-width-derived size matrix mode already\nsupports) governs calendar mode's grid too.\n\nFull canvas redraws are suspended while the host is outside the viewport. Data, locale, theme,\nresize, and DPR invalidations remain pending and coalesce into one redraw when the heatmap\nintersects again; environments without `IntersectionObserver` retain eager drawing.\nMatrix work is capped at `MAX_HEATMAP_CELLS`; calendar input/span and decoration collections\nhave corresponding exported ceilings. A localized `[part=\"projection-limit\"]` disclosure is\nattached whenever canonicalization truncates caller input.\nPublic data records and decoration collections are clone-owned, bounded readonly snapshots.\nCreate and reassign a new record or array after changing `data`, `annotations`, `legendStops`,\nor `colorSteps`.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The heatmap wrapper. |\n| `canvas` | The heatmap canvas. |\n| `cell` | An opt-in native button for one matrix or calendar cell. |\n| `cells` | The opt-in per-cell accessibility overlay. |\n| `legend` | The color legend. |\n| `legend-annotation` | An annotation label. |\n| `legend-hi` | The high legend endpoint (omitted when `legendStops` is supplied). |\n| `legend-lo` | The low legend endpoint (omitted when `legendStops` is supplied). |\n| `legend-stop` | One discrete `legendStops` entry — swatch plus label. |\n| `legend-stop-label` | The text of one `legendStops` entry. |\n| `legend-swatch` | The color swatch of one `legendStops` entry. Not rendered at all for a caption-only stop (one with no `color`). |\n| `legend-value-label` | The trailing `valueLabel` caption that closes the legend row, in both the gradient and the `legendStops` branch. |\n| `live-region` | An aria-hidden shadow mirror of the keyboard announcement; the actual announcement uses the shared light-DOM polite sink. |\n| `projection-limit` | Localized assistive disclosure for bounded projections. |\n| `tooltip` | The hover tooltip. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-heatmap-annotation-color` (default: `var(--lr-color-danger)`) — Border color for an annotated cell.\n- `--lr-heatmap-color-steps-gradient` (default: `linear-gradient(to right, var(--lr-heatmap-scale-lo), var(--lr-heatmap-scale-hi))`) — Gradient painted on the continuous legend bar. Set on the host by the component itself while `colorSteps` is supplied, and removed again when it is not; the fallback is the two-endpoint scale ramp.\n- `--lr-heatmap-focus-ring-color` (default: `var(--lr-focus-ring-color)`) — Focus ring around a focused cell.\n- `--lr-heatmap-label-font` — Font for axis/legend labels drawn on the canvas.\n- `--lr-heatmap-no-data-fill` (default: `var(--lr-color-no-data)`) — Fill for cells with no value.\n- `--lr-heatmap-scale-hi` (default: `var(--lr-color-brand)`) — High endpoint of the sequential color ramp.\n- `--lr-heatmap-scale-lo` (default: `var(--lr-color-brand-quiet)`) — Low endpoint of the sequential color ramp.\n- `--lr-heatmap-selected-color` (default: `var(--lr-color-success)`) — Border color for the selected cell.\n- `--lr-heatmap-tooltip-bg` (default: `var(--lr-color-surface)`) — Hover tooltip background.\n- `--lr-heatmap-tooltip-text` (default: `var(--lr-color-text)`) — Hover tooltip text color."
12138
+ "value": "`<lr-heatmap>` — a Canvas heatmap with a DPR-aware, resize-aware redraw\nloop. Its discriminated `data` property selects one of two projections:\n\n- `{ kind: \"matrix\", rowLabels, colLabels, values }` (default): a labeled matrix. `-1`\n (or any non-finite value) is treated as \"no data\". `scale=\"sqrt\"`\n compresses the ramp via `sqrtStep()` so one heavy cell doesn't wash out\n the rest; the default `\"linear\"` scale maps linearly instead.\n- `{ kind: \"calendar\", days, firstDayOfWeek?, columnX?, rowY?, ... }`: a GitHub-style\n weekday x week grid. `scale` governs its\n bucketing too: the default `\"linear\"` buckets by `quartileBucket()`\n (today's original behavior, unchanged); `\"sqrt\"` instead compresses via\n the same `sqrtStep()` magnitude compression matrix mode uses, so one\n heavy day doesn't wash out the rest. As in matrix mode, a cell whose\n `value` is negative or non-finite is treated as \"no data\" rather than\n being bucketed — as is a grid position with no matching entry in `days`\n at all (a gap in a sparse calendar).\n\n`fitToWidth` divides the host's measured width across the grid in either\nmode; `maxCellSize`/`minCellSize` bound the result, so a sparse grid in a\nwide pane cannot inflate into a few giant blocks and a year calendar in a\nnarrow one cannot collapse into hairlines. Both are ignored while\n`fitToWidth` is unset (an explicit `cellSize` is an exact request), and the\ncanvas is sized from the *clamped* size — a capped grid leaves the host's\nremaining width unfilled rather than stretching to it.\n\nThe sequential color ramp's endpoints are read from the\n`--lr-heatmap-scale-lo`/`-hi` custom properties (declared in\n`heatmap.styles.ts`) so hosts can retheme it — canvas can't consume\n`var()` directly, so they're resolved once per draw via\n`getComputedStyle`, then normalized to RGB by `resolveRgb()` (any valid\nCSS color syntax, not just hex — see its doc comment).\n\nEvery cell is independently addressable: a `pointermove` hit test over the\ncanvas shows `[part=\"tooltip\"]` with that cell's label + value (hidden on\n`pointerleave`); the canvas is a named `role=\"application\"`, `tabindex=\"0\"` control with\narrow-key roving focus (a stroked ring redrawn over the focused cell on every draw, plus a\nshared light-DOM polite status announcement — avoids a\nDOM-node-per-cell overlay, which would be hundreds of nodes for a year\ncalendar); and a click, or Enter/Space on the focused cell, fires\n`lr-cell-click`. `annotations` additionally strokes a ring around\nspecific cells (e.g. to call out an anomaly), each one optionally\nsurfaced in the legend too via `[part=\"legend-annotation\"]`.\n\nBoth grid modes deliberately retain physical LTR geometry under `dir=\"rtl\"`:\nmatrix column 0 and calendar week 0 remain at the physical left. ArrowLeft\nand ArrowRight therefore retain their physical previous/next movement rather\nthan swapping under RTL, matching the grid the user sees.\n\nIn calendar mode every cell position handed to `cellText`, `cellColor` and\n`cellInteractive` is a `CalendarCellPos` carrying the resolved ISO\n`yyyy-mm-dd` `date` alongside `week`/`weekday` — including for a grid\nposition with no entry in `days` at all — so a callback can key off the\ndate without re-deriving the grid's own anchor arithmetic.\n\n`legendStops` swaps the legend's two-endpoint gradient bar for a discrete\nkey of swatches, so a consumer whose `cellColor` callback paints an\nentirely different domain than the `--lr-heatmap-scale-lo`/`-hi` ramp can\nkeep the built-in legend (labels, number formatting, annotation entries)\ninstead of hiding `[part=\"legend\"]` and hand-rolling swatches. It is\npresentation only — it never feeds back into the cell colors.\n\nSet `accessibleCells` when cells need persistent DOM semantics for\nassistive technology. The opt-in semantic grid virtualizes native buttons to a bounded\nwindow while retaining full row/column counts, complete arrow navigation,\nlocalized `aria-label`, and explicit `aria-selected` state\nderived from the controlled `selectedCell` property; the canvas remains the\nvisual rendering surface underneath. When grid data refreshes while one of those buttons owns\nfocus, its semantic matrix coordinate or calendar date remains the sole roving stop; removal\nclamps to the nearest survivor, or to the stable heatmap base when no interactive cells remain.\n\n`stickyLabels` freezes a matrix label band against the grid's own scrolling — `'rows'` pins the\nrow-label gutter through horizontal scrolling, `'cols'` pins the column-label band through\nvertical scrolling, `'both'` pins both. The frozen band is repainted into its own layer from the\nsame `matrixGeometry` the cells were painted with in the same pass, so it tracks a\n`row-label-width`/`col-label-height` `\"auto\"` re-resolution instead of hardcoding it. The default\n`'none'` renders exactly what it always did: one canvas, no scrollport.\n\nEverything positioned in canvas coordinates moves into that scrollport with the cells. The hover\ntooltip renders inside it, so it stays on the cell it describes through a scroll instead of\ndrifting by the scroll offset; since `overflow: auto` there clips whatever leaves the\nscrollport, it is also kept inside the visible window — clamped along the inline axis, and\nflipped to below its cell when a frozen band leaves no room above. Arrow-key navigation scrolls\nthe focused cell into that window, clear of the frozen bands: the canvas is the roving tab stop,\nits focus ring is painted into the bitmap, and it calls `preventDefault()` on the arrows, so\nwithout that scroll a keyboard user has no way at all to bring the focused cell back into view.\n\nCalendar `data.columnX` overrides the x-origin computed for each\nweek column — drawing, hit-testing, the focus ring, and month-label\npositioning all consult it consistently, so a consumer can pixel-align a\ncalendar's week columns with a sibling chart's coordinate system. Unset\n(the default) keeps the original evenly-spaced formula. `data.rowY` is its\ncalendar-mode vertical analogue — overrides the y-origin computed for each\nweekday row, consulted consistently by drawing, hit-testing, and the focus\nring via the private `rowYFor()` helper (mirroring `columnXFor()` exactly).\n\n`data.firstDayOfWeek` (calendar only, default `0`/Sunday)\nanchors the calendar grid at a different weekday — `0`-`6`, same\nnumbering as `CalendarCellPos.weekday` (`0` Sunday .. `6` Saturday) —\nthreaded into `buildCalendarGrid()`.\n\n`cellSize`/`fitToWidth` (previously matrix-mode only) also drive calendar\nmode's per-cell size: unset, calendar mode keeps today's original 11px\ncell size unchanged; explicitly set, the same fixed size (or, with\n`fitToWidth`, the same host-width-derived size matrix mode already\nsupports) governs calendar mode's grid too.\n\nFull canvas redraws are suspended while the host is outside the viewport. Data, locale, theme,\nresize, and DPR invalidations remain pending and coalesce into one redraw when the heatmap\nintersects again; environments without `IntersectionObserver` retain eager drawing.\nMatrix work is capped at `MAX_HEATMAP_CELLS`; calendar input/span and decoration collections\nhave corresponding exported ceilings. A localized `[part=\"projection-limit\"]` disclosure is\nattached whenever canonicalization truncates caller input.\nPublic data records and decoration collections are clone-owned, bounded readonly snapshots.\nCreate and reassign a new record or array after changing `data`, `annotations`, `legendStops`,\nor `colorSteps`.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The heatmap wrapper. |\n| `canvas` | The heatmap canvas. |\n| `cell` | An opt-in native button for one matrix or calendar cell. |\n| `cells` | The opt-in per-cell accessibility overlay. |\n| `col-labels` | The frozen column-label band, rendered while `stickyLabels` is `cols` or `both`. |\n| `grid` | The scrollport wrapping the canvas while `stickyLabels` freezes an axis; absent otherwise. |\n| `legend` | The color legend. |\n| `legend-annotation` | An annotation label. |\n| `legend-hi` | The high legend endpoint (omitted when `legendStops` is supplied). |\n| `legend-lo` | The low legend endpoint (omitted when `legendStops` is supplied). |\n| `legend-stop` | One discrete `legendStops` entry — swatch plus label. |\n| `legend-stop-label` | The text of one `legendStops` entry. |\n| `legend-swatch` | The color swatch of one `legendStops` entry. Not rendered at all for a caption-only stop (one with no `color`). |\n| `legend-value-label` | The trailing `valueLabel` caption that closes the legend row, in both the gradient and the `legendStops` branch. |\n| `live-region` | An aria-hidden shadow mirror of the keyboard announcement; the actual announcement uses the shared light-DOM polite sink. |\n| `projection-limit` | Localized assistive disclosure for bounded projections. |\n| `row-labels` | The frozen row-label gutter, rendered while `stickyLabels` is `rows` or `both`. |\n| `tooltip` | The hover tooltip, positioned over the hovered cell. It renders inside `[part=\"grid\"]` while `stickyLabels` freezes an axis (so it scrolls with the cells) and as a `[part=\"base\"]` child otherwise. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-heatmap-annotation-color` (default: `var(--lr-color-danger)`) — Border color for an annotated cell.\n- `--lr-heatmap-color-steps-gradient` (default: `linear-gradient(to right, var(--lr-heatmap-scale-lo), var(--lr-heatmap-scale-hi))`) — Gradient painted on the continuous legend bar. Set on the host by the component itself while `colorSteps` is supplied, and removed again when it is not; the fallback is the two-endpoint scale ramp.\n- `--lr-heatmap-focus-ring-color` (default: `var(--lr-focus-ring-color)`) — Focus ring around a focused cell.\n- `--lr-heatmap-grid-max-block-size` (default: `none`) — Block-size ceiling of the `stickyLabels` scrollport. A frozen column band only stays behind once the grid actually scrolls vertically.\n- `--lr-heatmap-label-font` — Font for axis/legend labels drawn on the canvas.\n- `--lr-heatmap-no-data-fill` (default: `var(--lr-color-no-data)`) — Fill for cells with no value.\n- `--lr-heatmap-scale-hi` (default: `var(--lr-color-brand)`) — High endpoint of the sequential color ramp.\n- `--lr-heatmap-scale-lo` (default: `var(--lr-color-brand-quiet)`) — Low endpoint of the sequential color ramp.\n- `--lr-heatmap-selected-color` (default: `var(--lr-color-success)`) — Border color for the selected cell.\n- `--lr-heatmap-sticky-label-bg` (default: `var(--lr-color-surface)`) — Backdrop painted under a frozen `stickyLabels` band. Must be opaque: it covers the same labels the scrolling canvas painted underneath it.\n- `--lr-heatmap-tooltip-bg` (default: `var(--lr-color-surface)`) — Hover tooltip background.\n- `--lr-heatmap-tooltip-text` (default: `var(--lr-color-text)`) — Hover tooltip text color."
12081
12139
  },
12082
12140
  "attributes": [
12083
12141
  {
@@ -12172,6 +12230,27 @@
12172
12230
  }
12173
12231
  ]
12174
12232
  },
12233
+ {
12234
+ "name": "sticky-labels",
12235
+ "description": {
12236
+ "kind": "markdown",
12237
+ "value": "Freezes a matrix label band against the grid's own scrolling, instead of leaving it baked into\nthe scrolling bitmap. `'rows'` pins the row-label gutter so it survives horizontal scrolling,\n`'cols'` pins the column-label band so it survives vertical scrolling, `'both'` pins both, and\nthe default `'none'` renders exactly what this component rendered before the option existed:\none canvas, no scrollport, no extra elements.\n\nLabels and cells share one bitmap, so a band cannot be `position: sticky` on its own; a tall\nmatrix therefore scrolled its column header away and left the columns unidentifiable. Setting\nthis repaints the requested band into its own layer, in the same draw pass and from the same\nresolved `matrixGeometry` the cells were painted with, so the two cannot drift under scroll, a\nresize, a DPR change, or a `rowLabelWidth`/`colLabelHeight` `\"auto\"` re-resolution. That last\none is the point: a hand-rolled light-DOM mirror had to hardcode the gutter width, which made\nit mutually exclusive with `row-label-width=\"auto\"`.\n\nFreezing needs something to scroll, so the frozen modes wrap the grid in a `[part=\"grid\"]`\nscrollport. It is bounded inline by the host's own allocation (a matrix wider than a 320px host\nscrolls inside the component rather than overflowing it) and unbounded in block by default; set\n`--lr-heatmap-grid-max-block-size` to bound it, since a column band can only stay behind while\nthe grid actually scrolls vertically.\n\nMatrix mode only, like `matrixGeometry` and `lr-matrix-geometry-change`: calendar mode's axes\nare a different geometry (a fixed weekday gutter, a month band, and the optional `columnX`/\n`rowY` overrides), so this property is read but has no effect there.\n\nUnder `dir=\"rtl\"` the grid keeps this component's documented physical LTR geometry, so the\nscrollport is direction-pinned like the canvas already is and the bands then freeze against the\nlogical inline-start/block-start edges of that pinned box — which is to say the physical left\nand top, where the labels they duplicate are actually painted.\n\nSee `LyraHeatmapStickyLabels` for why this is one closed set rather than a boolean or a pair.\n\nType: `LyraHeatmapStickyLabels`"
12238
+ },
12239
+ "values": [
12240
+ {
12241
+ "name": "none"
12242
+ },
12243
+ {
12244
+ "name": "rows"
12245
+ },
12246
+ {
12247
+ "name": "cols"
12248
+ },
12249
+ {
12250
+ "name": "both"
12251
+ }
12252
+ ]
12253
+ },
12175
12254
  {
12176
12255
  "name": "value-label",
12177
12256
  "description": {
@@ -12264,7 +12343,7 @@
12264
12343
  "name": "description",
12265
12344
  "description": {
12266
12345
  "kind": "markdown",
12267
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
12346
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
12268
12347
  }
12269
12348
  },
12270
12349
  {
@@ -14194,7 +14273,7 @@
14194
14273
  "name": "description",
14195
14274
  "description": {
14196
14275
  "kind": "markdown",
14197
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
14276
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
14198
14277
  }
14199
14278
  },
14200
14279
  {
@@ -14414,7 +14493,7 @@
14414
14493
  "name": "lr-lite-chart",
14415
14494
  "description": {
14416
14495
  "kind": "markdown",
14417
- "value": "`<lr-lite-chart>` — a dependency-free bar/line chart, plain SVG/DOM\nrendering with zero peer dependencies (unlike `lr-chart`, which wraps\n`chart.js`). For a project whose architecture forbids a charting\ndependency outright, this covers the common bar/line case: grouped or\nstacked bars, multi-series lines, per-point click, and hover tooltips\n(native SVG `<title>`, no positioning JS needed) — not a full `lr-chart`\nreplacement (no zoom/pan, no pie/doughnut/radar/scatter/bubble types, no\nhorizontal/dual-y-axis, no raw-config passthrough, no interactive legend\ntoggle — unlike `lr-chart`/`lr-box-plot`, clicking a `legend-item` here does\nnot hide its series; the legend is a static color key).\n\nBecause this renders real DOM (not canvas), it reuses `lr-chart`'s\n`--lr-chart-*` theme tokens directly via CSS `var()` — no\n`getComputedStyle()`-based re-theming step is needed the way `chart.ts`\nneeds one for its canvas.\n\nBy default (`layout=\"fit\"`) the plot always squeezes to the measured host\nwidth. Three independent, opt-in escape hatches for dense/aligned data:\n`layout=\"scroll\"` (+ `barWidth`) gives every bar a fixed pixel width and\nlets the plot overflow the host horizontally (scrollable) instead of\nsqueezing; `maxLabels` decimates which x-axis text labels render (bars\nalways still render) once there are more categories than that; and\n`barX` lets a consumer hand in its own per-category x-coordinate function\n— e.g. to pixel-align this chart's bars with a sibling `lr-heatmap`'s\ncalendar columns — overriding the internal slot math for both bars and\ntheir labels. All three are additive and no-ops when left unset.\n\nSeven further additive, opt-in properties: `pointText` overrides the\nper-bar/per-point `<title>` tooltip and accessible-name text (mirrors\n`lr-heatmap`'s `cellText` hook), falling back to the built-in raw-value\ntemplate when unset; `roundedBars` draws bars as a rounded-top path\ninstead of a square-cornered rect; `skipZero` omits a bar entirely (not\njust zero-height) for an exactly-`0` value; `valueAxisGutter`/`barGapRatio`\noverride the internal `PAD_LEFT`/`BAR_GROUP_GAP` layout constants; `scale`\n(`type=\"bar\"` only) switches the bar-height mapping from the default\nlinear `niceDomain` fraction to a `Math.sqrt(value / domainMax)`\ncompression (mirroring `lr-heatmap`'s matrix-mode `sqrt` scale) so a\nskewed dataset's smaller bars don't get washed out by one dominant value\n— gridlines/tick labels stay on the linear domain regardless, only the bar\nmarks' own height changes, and `type=\"line\"` ignores `scale` entirely; and\n`withoutValueAxis` suppresses `renderGrid()`'s gridlines/tick labels altogether\n(x-axis category labels, rendered separately, are unaffected). An eighth,\n`legendText`, appends a formatter-supplied string after each series' label in the\nbuilt-in legend row (e.g. a value or share) — no-op while `legend` is unset, matching the same\nfallback-to-unchanged convention as every other hook here. The built-in multi-series accessible\ntable can independently format its finite numeric cells through `tableCellFormatter`; for a\nstacked bar chart, `tableTotals` adds an opt-in localized total column. Both are no-ops when\nunset.\n\nPublic collection properties take bounded, clone-owned readonly snapshots. Create a new\ncollection and reassign it after changes; mutating the assigned array does not update the view.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `data-table` | An optional consumer-provided complete/paginated accessible data alternative. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `axis-label` | Each axis tick label. |\n| `axis-title` | The x/y axis title text, when set. |\n| `bar` | Each bar rect (type=\"bar\"). Carries `data-selected` and `aria-pressed=\"true\"` when its category index is in `selectedIndices`. While `forced-colors: active` matches, its fill is a per-series SVG texture instead of a flat color, so series that collapse onto the same system color stay distinguishable. |\n| `base` | The host's flex layout wrapper. |\n| `data-list` | A visually hidden sampled list of plotted data points (single-series only). |\n| `data-table` | A visually hidden sampled category×series data table, rendered instead of `data-list` when there is more than one dataset so a screen-reader user hears series grouping rather than one flattened N×M sequence. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when built-in marks/data alternatives sample more than 1,000 records. |\n| `description` | The visually hidden accessible chart description, when set. |\n| `grid-line` | Each horizontal gridline. |\n| `legend` | The legend row, when `legend` is set. |\n| `legend-item` | Each legend entry. |\n| `legend-swatch` | Each legend entry's color swatch. While `forced-colors: active` matches, it carries a `data-encoding` attribute selecting the CSS texture that matches its series' plotted encoding. |\n| `legend-text` | Extra per-item text after the series label, rendered only when `legendText` is set. |\n| `line` | Each series' stroked line path (type=\"line\"). While `forced-colors: active` matches, it carries a per-series `stroke-dasharray` for the same reason. |\n| `live-region` | The current mark announcement for keyboard users. |\n| `point` | Each series' per-point keyboard target (type=\"line\"). Carries `data-selected` and explicit `aria-pressed` state. |\n| `table` | The generated semantic table inside the `data-table` container. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chart-color-1` (default: `var(--lr-color-chart-1)`) — First series color.\n- `--lr-chart-color-2` (default: `var(--lr-color-chart-2)`) — Second series color.\n- `--lr-chart-color-3` (default: `var(--lr-color-chart-3)`) — Third series color.\n- `--lr-chart-color-4` (default: `var(--lr-color-chart-4)`) — Fourth series color.\n- `--lr-chart-color-5` (default: `var(--lr-color-chart-5)`) — Fifth series color.\n- `--lr-chart-color-6` (default: `var(--lr-color-chart-6)`) — Sixth series color.\n- `--lr-chart-color-7` (default: `var(--lr-color-chart-7)`) — Seventh series color.\n- `--lr-chart-color-8` (default: `var(--lr-color-chart-8)`) — Eighth series color.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color.\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — Consumer-owned chart height. The `height` property supplies only a private fallback, so this public token always wins when set.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum side-legend track size.\n- `--lr-chart-pattern-step` (default: `var(--lr-space-2xs)`) — Tile size of the texture painted on `[part='legend-swatch']` while `forced-colors: active` matches, where the eight-color series ramp collapses onto a repeating system-color cycle and the texture becomes the only channel keeping series apart. Declared on the swatch part rather than the host; the stripe width within a tile stays `--lr-border-width-thin`, so a larger step spaces the stripes further apart. Shared verbatim with `<lr-chart>` and `<lr-box-plot>`.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis and legend-detail color.\n- `--lr-lite-chart-data-table-toggle-active-bg` — Pressed background of the `dataTableToggle` disclosure button; defaults to a mix of the hover background with the shared active mix partner.\n- `--lr-lite-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-lite-chart-selected-outline-color` (default: `var(--lr-color-brand)`) — Stroke for a bar/point whose category index is in `selectedIndices`.\n- `--lr-lite-chart-selected-outline-width` (default: `var(--lr-size-2px)`) — Stroke width for a bar/point whose category index is in `selectedIndices`."
14496
+ "value": "`<lr-lite-chart>` — a dependency-free bar/line chart, plain SVG/DOM\nrendering with zero peer dependencies (unlike `lr-chart`, which wraps\n`chart.js`). For a project whose architecture forbids a charting\ndependency outright, this covers the common bar/line case: grouped or\nstacked bars, multi-series lines, per-point click, and hover tooltips\n(native SVG `<title>`, no positioning JS needed) — not a full `lr-chart`\nreplacement (no zoom/pan, no pie/doughnut/radar/scatter/bubble types, no\nhorizontal/dual-y-axis, no raw-config passthrough, no interactive legend\ntoggle — unlike `lr-chart`/`lr-box-plot`, clicking a `legend-item` here does\nnot hide its series; the legend is a static color key).\n\nBecause this renders real DOM (not canvas), it reuses `lr-chart`'s\n`--lr-chart-*` theme tokens directly via CSS `var()` — no\n`getComputedStyle()`-based re-theming step is needed the way `chart.ts`\nneeds one for its canvas.\n\nBy default (`layout=\"fit\"`) the plot always squeezes to the measured host\nwidth. Three independent, opt-in escape hatches for dense/aligned data:\n`layout=\"scroll\"` (+ `barWidth`) gives every bar a fixed pixel width and\nlets the plot overflow the host horizontally (scrollable) instead of\nsqueezing; `maxLabels` decimates which x-axis text labels render (bars\nalways still render) once there are more categories than that, with\n`maxLabels=\"auto\"` deriving the cap from the allocated plot width; and\n`barX` lets a consumer hand in its own per-category x-coordinate function\n— e.g. to pixel-align this chart's bars with a sibling `lr-heatmap`'s\ncalendar columns — overriding the internal slot math for both bars and\ntheir labels. All three are additive and no-ops when left unset.\n\nSeven further additive, opt-in properties: `pointText` overrides the\nper-bar/per-point `<title>` tooltip and accessible-name text (mirrors\n`lr-heatmap`'s `cellText` hook), falling back to the built-in raw-value\ntemplate when unset; `roundedBars` draws bars as a rounded-top path\ninstead of a square-cornered rect; `skipZero` omits a bar entirely (not\njust zero-height) for an exactly-`0` value; `valueAxisGutter`/`barGapRatio`\noverride the internal `PAD_LEFT`/`BAR_GROUP_GAP` layout constants, while\n`valueAxisGutter=\"auto\"` sizes the gutter from the rendered tick strings; `scale`\n(`type=\"bar\"` only) switches the bar-height mapping from the default\nlinear `niceDomain` fraction to a `Math.sqrt(value / domainMax)`\ncompression (mirroring `lr-heatmap`'s matrix-mode `sqrt` scale) so a\nskewed dataset's smaller bars don't get washed out by one dominant value\n— gridlines/tick labels stay on the linear domain regardless, only the bar\nmarks' own height changes, and `type=\"line\"` ignores `scale` entirely; and\n`withoutValueAxis` suppresses `renderGrid()`'s gridlines/tick labels altogether\n(x-axis category labels, rendered separately, are unaffected). An eighth,\n`legendText`, appends a formatter-supplied string after each series' label in the\nbuilt-in legend row (e.g. a value or share) — no-op while `legend` is unset, matching the same\nfallback-to-unchanged convention as every other hook here. The built-in multi-series accessible\ntable can independently format its finite numeric cells through `tableCellFormatter`; for a\nstacked bar chart, `tableTotals` adds an opt-in localized total column. Both are no-ops when\nunset.\n\nPublic collection properties take bounded, clone-owned readonly snapshots. Create a new\ncollection and reassign it after changes; mutating the assigned array does not update the view.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `data-table` | An optional consumer-provided complete/paginated accessible data alternative. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `axis-label` | Each axis tick label. |\n| `axis-title` | The x/y axis title text, when set. |\n| `bar` | Each bar rect (type=\"bar\"). Carries `data-selected` and `aria-pressed=\"true\"` when its category index is in `selectedIndices`. While `forced-colors: active` matches, its fill is a per-series SVG texture instead of a flat color, so series that collapse onto the same system color stay distinguishable. |\n| `base` | The host's flex layout wrapper. |\n| `data-list` | A visually hidden sampled list of plotted data points (single-series only). |\n| `data-table` | A visually hidden sampled category×series data table, rendered instead of `data-list` when there is more than one dataset so a screen-reader user hears series grouping rather than one flattened N×M sequence. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when built-in marks/data alternatives sample more than 1,000 records. |\n| `description` | The visually hidden accessible chart description, when set. |\n| `grid-line` | Each horizontal gridline. |\n| `legend` | The legend row, when `legend` is set. |\n| `legend-item` | Each legend entry. |\n| `legend-swatch` | Each legend entry's color swatch. While `forced-colors: active` matches, it carries a `data-encoding` attribute selecting the CSS texture that matches its series' plotted encoding. |\n| `legend-text` | Extra per-item text after the series label, rendered only when `legendText` is set. |\n| `line` | Each series' stroked line path (type=\"line\"). While `forced-colors: active` matches, it carries a per-series `stroke-dasharray` for the same reason. |\n| `live-region` | The current mark announcement for keyboard users. |\n| `point` | Each series' per-point keyboard target (type=\"line\"). Carries `data-selected` and explicit `aria-pressed` state. |\n| `table` | The generated semantic table inside the `data-table` container. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chart-color-1` (default: `var(--lr-color-chart-1)`) — First series color.\n- `--lr-chart-color-2` (default: `var(--lr-color-chart-2)`) — Second series color.\n- `--lr-chart-color-3` (default: `var(--lr-color-chart-3)`) — Third series color.\n- `--lr-chart-color-4` (default: `var(--lr-color-chart-4)`) — Fourth series color.\n- `--lr-chart-color-5` (default: `var(--lr-color-chart-5)`) — Fifth series color.\n- `--lr-chart-color-6` (default: `var(--lr-color-chart-6)`) — Sixth series color.\n- `--lr-chart-color-7` (default: `var(--lr-color-chart-7)`) — Seventh series color.\n- `--lr-chart-color-8` (default: `var(--lr-color-chart-8)`) — Eighth series color.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color.\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — Consumer-owned chart height. The `height` property supplies only a private fallback, so this public token always wins when set.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum side-legend track size.\n- `--lr-chart-pattern-step` (default: `var(--lr-space-2xs)`) — Tile size of the texture painted on `[part='legend-swatch']` while `forced-colors: active` matches, where the eight-color series ramp collapses onto a repeating system-color cycle and the texture becomes the only channel keeping series apart. Declared on the swatch part rather than the host; the stripe width within a tile stays `--lr-border-width-thin`, so a larger step spaces the stripes further apart. Shared verbatim with `<lr-chart>` and `<lr-box-plot>`.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis and legend-detail color.\n- `--lr-lite-chart-data-table-toggle-active-bg` — Pressed background of the `dataTableToggle` disclosure button; defaults to a mix of the hover background with the shared active mix partner.\n- `--lr-lite-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-lite-chart-selected-outline-color` (default: `var(--lr-color-brand)`) — Stroke for a bar/point whose category index is in `selectedIndices`.\n- `--lr-lite-chart-selected-outline-width` (default: `var(--lr-size-2px)`) — Stroke width for a bar/point whose category index is in `selectedIndices`."
14418
14497
  },
14419
14498
  "attributes": [
14420
14499
  {
@@ -14527,7 +14606,7 @@
14527
14606
  "name": "max-labels",
14528
14607
  "description": {
14529
14608
  "kind": "markdown",
14530
- "value": "Caps how many x-axis category labels render text once `this.labels.length` exceeds it,\ndecimating roughly evenly while always keeping the first and last label. Bars themselves\nalways render regardless — only the axis text is decimated. Unset (the default) renders every\nlabel, unchanged from before this property existed. Works in either `layout` mode.\n\nType: `number | undefined`"
14609
+ "value": "Caps how many x-axis category labels render text once `this.labels.length` exceeds it,\ndecimating roughly evenly while always keeping the first and last label. `'auto'` derives a\ndeterministic cap from the resolved plot width and widest rendered category label using the\nsame width estimate as label ellipsis. Bars themselves always render regardless — only the\naxis text is decimated. An explicit number is authoritative. Unset (the default) renders every\nlabel, unchanged from before this property existed. Works in either `layout` mode.\n\nType: `number | 'auto' | undefined`"
14531
14610
  }
14532
14611
  },
14533
14612
  {
@@ -14609,7 +14688,7 @@
14609
14688
  "name": "value-axis-gutter",
14610
14689
  "description": {
14611
14690
  "kind": "markdown",
14612
- "value": "Overrides the internal `PAD_LEFT` (36px) axis-gutter constant. The gutter is on the left in\nLTR and the right in RTL, keeping the y axis at logical start. Unset keeps the 36px default.\n\nType: `number | undefined`"
14691
+ "value": "Overrides the internal `PAD_LEFT` (36px) axis-gutter constant, or accepts `'auto'` to size the\ngutter from the exact formatted tick strings rendered in the current pass. Automatic sizing\nnever shrinks below 36px. Fit layout bounds it to the smaller of 240px or 40% of the measured\nSVG width; scroll layout bounds it at 240px without feeding the explicitly-sized SVG's own\nwidth back into its gutter. An explicit numeric value is authoritative and retains the\nestablished 0..1,000,000px finite guard. The gutter is on the left in LTR and the right in\nRTL, keeping the y axis at logical start. Unset keeps the 36px default.\n\nType: `number | 'auto' | undefined`"
14613
14692
  }
14614
14693
  },
14615
14694
  {
@@ -14806,7 +14885,7 @@
14806
14885
  "name": "lr-map",
14807
14886
  "description": {
14808
14887
  "kind": "markdown",
14809
- "value": "`<lr-map>` — a maplibre-gl wrapper with a declarative legend, choropleth\nGeoJSON layer, markers, and additive `dataLayers` GeoJSON overlays\n(arbitrary shapes rendered as a source plus fill/line/circle layers,\nindependent of `choropleth`'s field/stops color-interpolation), plus a peer-neutral\n`map` getter for common imperative operations. Its runtime value is the underlying MapLibre\nmap, while its declaration stays independent of the optional peer. Requires `maplibre-gl`\nv5 or v6; the component styles MapLibre's generated canvas, marker, popup, and control DOM\ninside its shadow root. MapLibre v6 is ESM-only, requires WebGL2, and needs its module-worker\nURL configured once; v5's standard build includes its worker.\n\nThe underlying `maplibregl.Map` — and the WebGL context it opens — isn't\nconstructed until this element is first visible in the viewport (tracked\nvia `IntersectionObserver`), even once the `maplibre-gl` peer dependency\nhas finished loading. Browsers hard-cap concurrent WebGL contexts per\npage, so a grid/dashboard of many `<lr-map>` instances only constructs\nthe ones actually on-screen instead of racing to exhaust that budget the\ninstant each one mounts. `map` stays `undefined` (and `lr-map-load`\ndoesn't fire) until construction actually happens.\n\nCall `LyraMap.preload()` before connecting an element to start the optional\npeer import early. `dataLayers[].sourceId` is a trimmed nonempty business identity; the first\noccurrence is retained and blanks or later duplicates are ignored. It is declarative component input;\nits backing MapLibre source and layers use collision-free component-owned\nids and must not be accessed through `map`.\n\nCollection-bearing inputs take bounded, recursively frozen snapshots synchronously. Mutate a\ncopy and reassign it to update the map; later changes to the assigned source are not observed.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `legend` | Custom legend content, rendered inside the legend panel's own layout so it stays positioned with the map instead of floating beside it. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `attribution` | MapLibre-generated map attribution. |\n| `attribution-toggle` | MapLibre's compact-attribution disclosure control. |\n| `base` | The non-semantic map wrapper. It exposes `aria-busy=\"true\"` while the optional map library loads and contains ordinary, non-live localized loading text. |\n| `container` | The MapLibre container. Its generated canvas is the actual focusable map region and receives the host-first accessible name and effective locale. |\n| `error` | Visible localized message shown instead of `container` when `mapStyle` is missing, the optional peer is unavailable, WebGL2 cannot be created, or map initialization fails; the transition is announced through the shared light-DOM assertive region. |\n| `legend` | The map legend. |\n| `legend-gradient` | The continuous ramp bar rendered from `legendGradient`. |\n| `legend-hi` | The high endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`). |\n| `legend-limit` | Visible localized summary when legend input is bounded or shortened. |\n| `legend-lo` | The low endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`). |\n| `legend-swatch` | A legend color swatch. |\n| `marker` | A MapLibre-generated marker, with a 24px minimum target in both axes even when a peer/custom marker has no intrinsic content size. |\n| `popup` | A MapLibre-generated marker popup. |\n| `popup-close-button` | The MapLibre-generated button that closes an open marker popup. |\n| `popup-content` | The content container inside a MapLibre-generated marker popup. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-map-choropleth-fill-opacity` (default: `0.75`) — Fill opacity for choropleth and polygon `dataLayers` fills. Read from the resolved cascade whenever those layers are applied or painted after a theme change.\n- `--lr-map-popup-close-button-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of `popup-close-button`.\n- `--lr-map-popup-close-button-active-color` (default: `var(--lr-color-brand)`) — Pressed foreground of `popup-close-button`. No style or tile provider is selected implicitly. Set `mapStyle` explicitly before connection; this prevents a bare component from making an undeclared third-party request.\n- `--lr-map-popup-close-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of `popup-close-button`.\n- `--lr-map-popup-close-button-hover-color` (default: `var(--lr-color-brand)`) — Hover foreground of `popup-close-button`."
14888
+ "value": "`<lr-map>` — a maplibre-gl wrapper with a declarative legend, choropleth\nGeoJSON layer, markers, and additive `dataLayers` GeoJSON overlays\n(arbitrary shapes rendered as a source plus fill/line/circle layers, or — opting in per entry —\nas a natively clustered point set or a `heatmap` density surface,\nindependent of `choropleth`'s field/stops color-interpolation), plus a peer-neutral\n`map` getter for common imperative operations. Its runtime value is the underlying MapLibre\nmap, while its declaration stays independent of the optional peer. Requires `maplibre-gl`\nv5 or v6; the component styles MapLibre's generated canvas, marker, popup, and control DOM\ninside its shadow root. MapLibre v6 is ESM-only, requires WebGL2, and needs its module-worker\nURL configured once; v5's standard build includes its worker.\n\nThe underlying `maplibregl.Map` — and the WebGL context it opens — isn't\nconstructed until this element is first visible in the viewport (tracked\nvia `IntersectionObserver`), even once the `maplibre-gl` peer dependency\nhas finished loading. Browsers hard-cap concurrent WebGL contexts per\npage, so a grid/dashboard of many `<lr-map>` instances only constructs\nthe ones actually on-screen instead of racing to exhaust that budget the\ninstant each one mounts. `map` stays `undefined` (and `lr-map-load`\ndoesn't fire) until construction actually happens.\n\nCall `LyraMap.preload()` before connecting an element to start the optional\npeer import early. `dataLayers[].sourceId` is a trimmed nonempty business identity; the first\noccurrence is retained and blanks or later duplicates are ignored. It is declarative component input;\nits backing MapLibre source and layers use collision-free component-owned\nids and must not be accessed through `map`.\n\nCollection-bearing inputs take bounded, recursively frozen snapshots synchronously. Mutate a\ncopy and reassign it to update the map; later changes to the assigned source are not observed.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `legend` | Custom legend content, rendered inside the legend panel's own layout so it stays positioned with the map instead of floating beside it. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `attribution` | MapLibre-generated map attribution. |\n| `attribution-toggle` | MapLibre's compact-attribution disclosure control. |\n| `base` | The non-semantic map wrapper. It exposes `aria-busy=\"true\"` while the optional map library loads and contains ordinary, non-live localized loading text. |\n| `container` | The MapLibre container. Its generated canvas is the actual focusable map region and receives the host-first accessible name and effective locale. |\n| `error` | Visible localized message shown instead of `container` when `mapStyle` is missing, the optional peer is unavailable, WebGL2 cannot be created, or map initialization fails; the transition is announced through the shared light-DOM assertive region. |\n| `legend` | The map legend. |\n| `legend-gradient` | The continuous ramp bar rendered from `legendGradient`. |\n| `legend-hi` | The high endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`). |\n| `legend-limit` | Visible localized summary when legend input is bounded or shortened. |\n| `legend-lo` | The low endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`). |\n| `legend-swatch` | A legend color swatch. |\n| `marker` | A MapLibre-generated marker, with a 24px minimum target in both axes even when a peer/custom marker has no intrinsic content size. |\n| `popup` | A MapLibre-generated marker popup. |\n| `popup-close-button` | The MapLibre-generated button that closes an open marker popup. |\n| `popup-content` | The content container inside a MapLibre-generated marker popup. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-map-choropleth-fill-opacity` (default: `0.75`) — Fill opacity for choropleth and polygon `dataLayers` fills. Read from the resolved cascade whenever those layers are applied or painted after a theme change.\n- `--lr-map-popup-close-button-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of `popup-close-button`.\n- `--lr-map-popup-close-button-active-color` (default: `var(--lr-color-brand)`) — Pressed foreground of `popup-close-button`. No style or tile provider is selected implicitly. Set `mapStyle` explicitly before connection; this prevents a bare component from making an undeclared third-party request.\n- `--lr-map-popup-close-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of `popup-close-button`.\n- `--lr-map-popup-close-button-hover-color` (default: `var(--lr-color-brand)`) — Hover foreground of `popup-close-button`."
14810
14889
  },
14811
14890
  "attributes": [
14812
14891
  {
@@ -18181,7 +18260,7 @@
18181
18260
  "name": "description",
18182
18261
  "description": {
18183
18262
  "kind": "markdown",
18184
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
18263
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
18185
18264
  }
18186
18265
  },
18187
18266
  {
@@ -18443,7 +18522,7 @@
18443
18522
  "name": "description",
18444
18523
  "description": {
18445
18524
  "kind": "markdown",
18446
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
18525
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
18447
18526
  }
18448
18527
  },
18449
18528
  {
@@ -19936,7 +20015,7 @@
19936
20015
  "name": "description",
19937
20016
  "description": {
19938
20017
  "kind": "markdown",
19939
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
20018
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
19940
20019
  }
19941
20020
  },
19942
20021
  {
@@ -21775,7 +21854,7 @@
21775
21854
  "name": "description",
21776
21855
  "description": {
21777
21856
  "kind": "markdown",
21778
- "value": "Accessible chart description.\n\nType: `string | null` \nDefault: `null`"
21857
+ "value": "Accessible chart description, which REPLACES the generated summary rather than adding to it.\n\nLeft unset, the component builds an sr-only per-series summary from the actual data. Setting\nthis discards that summary entirely and substitutes your text -- a full override, which is the\nright tool when you can describe the chart better than a generic walk of the series can.\n\nIt is the wrong tool for adding a caveat (\"excludes returns\", \"sampled hourly\") on top of the\ndata summary: you would trade the whole summary for the caveat, and a consumer reasonably read\nthe old one-line doc as additive and did exactly that. For a caveat, prefer visible text beside\nthe chart -- a note only screen-reader users hear is worse for everyone than one everybody\nsees -- or fold the data into your own `description` text if you are overriding anyway.\n\nType: `string | null` \nDefault: `null`"
21779
21858
  }
21780
21859
  },
21781
21860
  {
@@ -24562,7 +24641,7 @@
24562
24641
  "name": "scroll-mode",
24563
24642
  "description": {
24564
24643
  "kind": "markdown",
24565
- "value": "Which element scrolls when the table overflows; see `TableScrollMode`. Defaults to `'self'`,\nwhich is the pre-10.0 behaviour.\n\nType: `TableScrollMode` \nDefault: `'self'`"
24644
+ "value": "Which element scrolls when the table overflows; see `TableScrollMode`. `'auto'` keeps page\nflow while content fits and contains horizontal overflow only when needed. Defaults to\n`'self'`, which is the pre-10.0 behaviour.\n\nType: `TableScrollMode` \nDefault: `'self'`"
24566
24645
  },
24567
24646
  "values": [
24568
24647
  {
@@ -24570,6 +24649,9 @@
24570
24649
  },
24571
24650
  {
24572
24651
  "name": "page"
24652
+ },
24653
+ {
24654
+ "name": "auto"
24573
24655
  }
24574
24656
  ]
24575
24657
  },
@@ -25959,7 +26041,7 @@
25959
26041
  "name": "lr-timeline",
25960
26042
  "description": {
25961
26043
  "kind": "markdown",
25962
- "value": "`<lr-timeline>` — an ordered, connected sequence of past-event rows (an audit trail, an agent\naction history, a changelog) composed from `<lr-timeline-item>` light-DOM children, joined by a\ncontinuous connecting rail. First-party invention: no Web Awesome/Shoelace counterpart exists, so\nthis follows the library's own established conventions rather than mirroring an upstream API.\n\nA pure, read-only, declarative display component — same zero-event shape as `<lr-badge>`/\n`<lr-avatar>`/`<lr-skeleton>`. It never mutates its own children and fires no events; a\nconsumer who needs to react to item count changes already owns the mutation (they're the one\nadding/removing `<lr-timeline-item>` children) and can listen to the native `slotchange` event\ndirectly if truly needed.\n\nNo keyboard navigation, roving-tabindex, or selection model of any kind a deliberate scope\ndecision, not an oversight. A timeline is a passive record display, not a navigable widget; see\n`<lr-timeline-item>`'s class doc for the full reasoning behind dropping an earlier\n\"interactive row\" design. Not a form-associated control no value to submit, no label/hint/error\nchrome.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | `<lr-timeline-item>` children, in display order. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. `role=\"list\"` lives here directly (a timeline isn't a navigation landmark, so it doesn't need a two-layer `base`+`list` split). Flex container: `flex-direction: column` in `vertical` orientation (the default), `flex-direction: row` (with `overflow-x: auto`, `overflow-y: hidden`, and an edge-fade `mask-image` applied only while the strip actually overflows) in `horizontal` orientation. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroll-fade-size` (default: `2rem`) — Inline size of each edge fade while a horizontal timeline overflows. Forced-colors mode disables the masks while retaining native scrolling.\n- `--lr-timeline-collision-offset` (default: `var(--lr-space-l)`) — Cross-axis step between items stacked by `collision=\"stack\"`. Each collision lane is indented one step further, so a wider marker can claim more room without the lanes overlapping again. Ignored unless both `scale=\"time\"` and `collision=\"stack\"` are set.\n- `--lr-timeline-gap` (default: `var(--lr-space-l)`) — Spacing between consecutive items along the timeline's main axis; also the length each item's own rail visually bridges to reach the next item's marker. Declared here but actually consumed inside each `<lr-timeline-item>`'s own stylesheet, via ordinary CSS custom-property inheritance across the slot boundary.\n- `--lr-timeline-time-extent` (default: `var(--lr-size-20rem)`) — Distance the `scale=\"time\"` axis distributes items along: `block-size` when vertical, `inline-size` when horizontal. Time-scaled items are absolutely positioned, and a percentage offset against an auto-sized track resolves to zero, so the axis needs a definite extent. Ignored in the default `scale=\"flow\"`."
26044
+ "value": "`<lr-timeline>` — an ordered, connected sequence of past-event rows (an audit trail, an agent\naction history, a changelog) composed from `<lr-timeline-item>` light-DOM children, joined by a\ncontinuous connecting rail. First-party invention: no Web Awesome/Shoelace counterpart exists, so\nthis follows the library's own established conventions rather than mirroring an upstream API.\n\nA read-only declarative display by default — same zero-interaction shape as `<lr-badge>`/\n`<lr-avatar>`/`<lr-skeleton>`. The opt-in `scale=\"time\" collision=\"cluster\"` presentation is the\none exception: overlapping events collapse behind a native count button and activation emits\ntheir exact element identities so the consumer can open its own popover, dialog, or detail\nview. The component does not select, expand, reorder, or mutate the content of those items.\n\nNo roving-tabindex or per-event selection model is introduced. Timeline items remain passive;\neach cluster marker is an independent native `<button>` in the normal Tab sequence, so pointer,\nEnter, and Space activation require no custom keyboard model. Not a form-associated control —\nno value to submit, no label/hint/error chrome.\n\nThe first member in document order represents a cluster: its ordinary shadow row is temporarily\nreplaced by the count action while the remaining members are hidden. This preserves the author's\nlist and Tab order instead of appending visually positioned controls after the slot. The action\nexposes `cluster` and `cluster-count` parts on that representative `<lr-timeline-item>`.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | `<lr-timeline-item>` children, in display order. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. `role=\"list\"` lives here directly (a timeline isn't a navigation landmark, so it doesn't need a two-layer `base`+`list` split). Flex container: `flex-direction: column` in `vertical` orientation (the default), `flex-direction: row` (with `overflow-x: auto`, `overflow-y: hidden`, and an edge-fade `mask-image` applied only while the strip actually overflows) in `horizontal` orientation. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroll-fade-size` (default: `2rem`) — Inline size of each edge fade while a horizontal timeline overflows. Forced-colors mode disables the masks while retaining native scrolling.\n- `--lr-timeline-cluster-bg` (default: `var(--lr-color-brand)`) — Cluster count pill background.\n- `--lr-timeline-cluster-color` (default: `var(--lr-color-on-brand)`) — Cluster count pill foreground.\n- `--lr-timeline-cluster-size` (default: `var(--lr-size-2rem)`) — Minimum inline and block size of the painted count pill. Its containing button retains the shared 40px minimum action surface.\n- `--lr-timeline-collision-offset` (default: `var(--lr-space-l)`) — Cross-axis step between items stacked by `collision=\"stack\"`. Each collision lane is indented one step further, so a wider marker can claim more room without the lanes overlapping again. Ignored unless both `scale=\"time\"` and `collision=\"stack\"` are set.\n- `--lr-timeline-gap` (default: `var(--lr-space-l)`) — Spacing between consecutive items along the timeline's main axis; also the length each item's own rail visually bridges to reach the next item's marker. Declared here but actually consumed inside each `<lr-timeline-item>`'s own stylesheet, via ordinary CSS custom-property inheritance across the slot boundary.\n- `--lr-timeline-time-extent` (default: `var(--lr-size-20rem)`) — Distance the `scale=\"time\"` axis distributes items along: `block-size` when vertical, `inline-size` when horizontal. Time-scaled items are absolutely positioned, and a percentage offset against an auto-sized track resolves to zero, so the axis needs a definite extent. Ignored in the default `scale=\"flow\"`."
25963
26045
  },
25964
26046
  "attributes": [
25965
26047
  {
@@ -25981,6 +26063,9 @@
25981
26063
  },
25982
26064
  {
25983
26065
  "name": "stack"
26066
+ },
26067
+ {
26068
+ "name": "cluster"
25984
26069
  }
25985
26070
  ]
25986
26071
  },
@@ -26027,7 +26112,7 @@
26027
26112
  "name": "lr-timeline-item",
26028
26113
  "description": {
26029
26114
  "kind": "markdown",
26030
- "value": "`<lr-timeline-item>` — one marker + title + optional timestamp + optional description row inside\n`<lr-timeline>`'s default slot. See that component's class doc for the overall shape; this class\ndoc covers the rail-connecting mechanism this item's own `[part=\"track\"]`/`[part=\"rail\"]`\nimplement.\n\nEach item owns and renders *its own trailing rail segment*, not the whole connecting line — think\nof it as a linked list of line segments, one per item, each reaching toward the next item's marker.\n`[part=\"track\"]` (marker then rail) is a flex sibling of `[part=\"content\"]` inside `[part=\"base\"]`,\nwith `[part=\"base\"]`'s default `align-items: stretch` left alone — so `[part=\"track\"]`'s\ncross-axis size automatically equals `[part=\"content\"]`'s own size, including any content-driven\nheight from a long slotted description. `[part=\"rail\"]` is `flex: 1 1 auto` inside `[part=\"track\"]`,\nso once the marker (fixed size) takes its share, the rail fills the rest — no JS measurement, no\n`ResizeObserver`, no absolute positioning. `[part=\"content\"]` carries a trailing logical padding\n(block-end in vertical mode, inline-end in horizontal mode) equal to `<lr-timeline>`'s\n`--lr-timeline-gap`, so the stretched rail visually reaches *into* the gap before the next item's\nmarker with no seam. The last item's rail is suppressed by `<lr-timeline>`'s own pure-CSS\n`::slotted(:last-child)` rule (see that component's stylesheet) — no JS coordination between the\ntwo components is needed anywhere in this mechanism.\n\nA pure display row: no events, no keyboard interaction, and no selection/expansion state of its\nown — a deliberate scope decision, not an oversight. An earlier \"interactive row\" design (mirroring\n`<lr-conversation-item>`'s clickable `role=\"button\"` row) was considered and dropped: this\ncomponent's `title` and `description` are slots that routinely contain focusable content of their\nown (a link, a button) — wrapping them in an ancestor `role=\"button\"` would trip axe's\n`nested-interactive` rule the moment a consumer slots one in, unlike `<lr-conversation-item>`,\nwhich keeps its own focusable content in a sibling `actions` slot specifically to avoid that. A\nconsumer who wants a clickable entry slots an actual interactive element inside `description`\nthemselves — `role=\"listitem\"` places no restriction on focusable descendants. Not a\nform-associated control — no value to submit, no label/hint/error chrome.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The item's primary heading/title content. Rich content allowed (inline code, a badge, a link) — nothing renders when this slot is empty, a valid if unusual usage. |\n| `description` | Secondary/body content below the title (explanatory text, a diff snippet, a \"view details\" affordance). `[part=\"description\"]` is hidden entirely when this slot is empty. |\n| `marker-icon` | Marker/glyph override (e.g. a `<lr-icon>`, an emoji, a small avatar-like element). When empty, the marker falls back to a plain color-coded dot driven by `variant`. |\n| `timestamp` | Full override of the timestamp presentation (e.g. `<lr-format-date slot=\"timestamp\">`, a custom string, a differently-configured `<lr-relative-time>`). Wins over the `timestamp` property whenever it has assigned content, even if `timestamp` is also set. Falls back to an internally-rendered `<lr-relative-time>` (driven by the `timestamp` property) wrapped in a `<time>`, or renders nothing at all (`[part=\"timestamp\"]` hidden) when neither the slot nor a valid `timestamp` is present. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. Flex container; `flex-direction` is driven by the parent timeline's private cross-shadow orientation state -- `row` in vertical-timeline mode (marker beside content), `column` in horizontal-timeline mode (marker above content). |\n| `content` | Wrapper around `header` and `description`. |\n| `description` | Wrapper around the `description` slot. Hidden entirely when the slot is empty. |\n| `header` | Flex row wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating either. |\n| `marker` | The dot/icon circle. Always `aria-hidden=\"true\"` -- purely decorative, the item's accessible content is its title/timestamp/description text. |\n| `rail` | The connecting line segment extending from this item's marker toward the next item's marker. Hidden (`visibility: hidden`, not removed) for the last item in a `<lr-timeline>` -- see the class doc. |\n| `timestamp` | Wrapper around the `timestamp` slot / the internally-rendered `<time>` fallback. Hidden entirely when there's nothing to show. |\n| `title` | Wrapper around the default (title) slot. |\n| `track` | Wrapper around the marker and rail (the \"spine\"). Always the opposite axis from `[part=\"base\"]` -- see the class doc's rail-mechanism note. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-timeline-active-ring-color` (default: `var(--lr-timeline-marker-color)`) — Static outline color for the current/in-progress marker. The outline remains visible when reduced motion disables the optional pulse animation.\n- `--lr-timeline-marker-color` (default: `var(--lr-color-text-quiet)`) — Marker fill/accent color. Its private default changes per `variant` (see the class doc's variant table); a consumer can override it on an ancestor for a themed group or directly on one item, with the direct value winning via the normal cascade.\n- `--lr-timeline-marker-size` (default: `var(--lr-size-1-25rem)`) — Diameter of the marker circle (both inline-size and block-size, so the default dot stays circular). Inherits from theme ancestors.\n- `--lr-timeline-rail-color` (default: `var(--lr-color-border)`) — Color of the connecting rail line. A component-scoped property (not just inlining `var(--lr-color-border)` at every use site) so a consumer can retint just the rail without touching the library-wide border color elsewhere. Inherits from theme ancestors.\n- `--lr-timeline-rail-width` (default: `var(--lr-border-width-medium)`) — Thickness of the connecting rail line. Inherits from theme ancestors."
26115
+ "value": "`<lr-timeline-item>` — one marker + title + optional timestamp + optional description row inside\n`<lr-timeline>`'s default slot. See that component's class doc for the overall shape; this class\ndoc covers the rail-connecting mechanism this item's own `[part=\"track\"]`/`[part=\"rail\"]`\nimplement.\n\nEach item owns and renders *its own trailing rail segment*, not the whole connecting line — think\nof it as a linked list of line segments, one per item, each reaching toward the next item's marker.\n`[part=\"track\"]` (marker then rail) is a flex sibling of `[part=\"content\"]` inside `[part=\"base\"]`,\nwith `[part=\"base\"]`'s default `align-items: stretch` left alone — so `[part=\"track\"]`'s\ncross-axis size automatically equals `[part=\"content\"]`'s own size, including any content-driven\nheight from a long slotted description. `[part=\"rail\"]` is `flex: 1 1 auto` inside `[part=\"track\"]`,\nso once the marker (fixed size) takes its share, the rail fills the rest — no JS measurement, no\n`ResizeObserver`, no absolute positioning. `[part=\"content\"]` carries a trailing logical padding\n(block-end in vertical mode, inline-end in horizontal mode) equal to `<lr-timeline>`'s\n`--lr-timeline-gap`, so the stretched rail visually reaches *into* the gap before the next item's\nmarker with no seam. The last item's rail is suppressed by `<lr-timeline>`'s own pure-CSS\n`::slotted(:last-child)` rule (see that component's stylesheet) — no JS coordination between the\ntwo components is needed anywhere in this mechanism.\n\nA pure display row by default: no events, no keyboard interaction, and no selection/expansion\nstate of its own — a deliberate scope decision, not an oversight. When a parent timeline opts\ninto collision clustering, the first item in each author-ordered group temporarily represents\nthat group with a native count button in this item's list position; activation still belongs to\nthe parent timeline and emits its `lr-cluster-activate` event. An earlier \"interactive row\"\ndesign (mirroring\n`<lr-conversation-item>`'s clickable `role=\"button\"` row) was considered and dropped: this\ncomponent's `title` and `description` are slots that routinely contain focusable content of their\nown (a link, a button) — wrapping them in an ancestor `role=\"button\"` would trip axe's\n`nested-interactive` rule the moment a consumer slots one in, unlike `<lr-conversation-item>`,\nwhich keeps its own focusable content in a sibling `actions` slot specifically to avoid that. A\nconsumer who wants a clickable entry slots an actual interactive element inside `description`\nthemselves — `role=\"listitem\"` places no restriction on focusable descendants. Not a\nform-associated control — no value to submit, no label/hint/error chrome.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The item's primary heading/title content. Rich content allowed (inline code, a badge, a link) — nothing renders when this slot is empty, a valid if unusual usage. |\n| `description` | Secondary/body content below the title (explanatory text, a diff snippet, a \"view details\" affordance). `[part=\"description\"]` is hidden entirely when this slot is empty. |\n| `marker-icon` | Marker/glyph override (e.g. a `<lr-icon>`, an emoji, a small avatar-like element). When empty, the marker falls back to a plain color-coded dot driven by `variant`. |\n| `timestamp` | Full override of the timestamp presentation (e.g. `<lr-format-date slot=\"timestamp\">`, a custom string, a differently-configured `<lr-relative-time>`). Wins over the `timestamp` property whenever it has assigned content, even if `timestamp` is also set. Falls back to an internally-rendered `<lr-relative-time>` (driven by the `timestamp` property) wrapped in a `<time>`, or renders nothing at all (`[part=\"timestamp\"]` hidden) when neither the slot nor a valid `timestamp` is present. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. Flex container; `flex-direction` is driven by the parent timeline's private cross-shadow orientation state -- `row` in vertical-timeline mode (marker beside content), `column` in horizontal-timeline mode (marker above content). |\n| `cluster` | The native count-marker button rendered while this item represents a parent timeline collision cluster; retains the shared 40px minimum action surface. |\n| `cluster-count` | The painted count pill inside a representative cluster button. |\n| `content` | Wrapper around `header` and `description`. |\n| `description` | Wrapper around the `description` slot. Hidden entirely when the slot is empty. |\n| `header` | Flex row wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating either. |\n| `marker` | The dot/icon circle. Always `aria-hidden=\"true\"` -- purely decorative, the item's accessible content is its title/timestamp/description text. |\n| `rail` | The connecting line segment extending from this item's marker toward the next item's marker. Hidden (`visibility: hidden`, not removed) for the last item in a `<lr-timeline>` -- see the class doc. |\n| `timestamp` | Wrapper around the `timestamp` slot / the internally-rendered `<time>` fallback. Hidden entirely when there's nothing to show. |\n| `title` | Wrapper around the default (title) slot. |\n| `track` | Wrapper around the marker and rail (the \"spine\"). Always the opposite axis from `[part=\"base\"]` -- see the class doc's rail-mechanism note. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-timeline-active-ring-color` (default: `var(--lr-timeline-marker-color)`) — Static outline color for the current/in-progress marker. The outline remains visible when reduced motion disables the optional pulse animation.\n- `--lr-timeline-cluster-bg` (default: `var(--lr-color-brand)`) — Cluster count pill background.\n- `--lr-timeline-cluster-color` (default: `var(--lr-color-on-brand)`) — Cluster count pill foreground.\n- `--lr-timeline-cluster-size` (default: `var(--lr-size-2rem)`) — Minimum inline and block size of the painted cluster count pill. Its containing button retains the shared 40px minimum action surface.\n- `--lr-timeline-marker-color` (default: `var(--lr-color-text-quiet)`) — Marker fill/accent color. Its private default changes per `variant` (see the class doc's variant table); a consumer can override it on an ancestor for a themed group or directly on one item, with the direct value winning via the normal cascade.\n- `--lr-timeline-marker-size` (default: `var(--lr-size-1-25rem)`) — Diameter of the marker circle (both inline-size and block-size, so the default dot stays circular). Inherits from theme ancestors.\n- `--lr-timeline-rail-color` (default: `var(--lr-color-border)`) — Color of the connecting rail line. A component-scoped property (not just inlining `var(--lr-color-border)` at every use site) so a consumer can retint just the rail without touching the library-wide border color elsewhere. Inherits from theme ancestors.\n- `--lr-timeline-rail-width` (default: `var(--lr-border-width-medium)`) — Thickness of the connecting rail line. Inherits from theme ancestors."
26031
26116
  },
26032
26117
  "attributes": [
26033
26118
  {
@@ -28044,7 +28129,7 @@
28044
28129
  "name": "lr-widget",
28045
28130
  "description": {
28046
28131
  "kind": "markdown",
28047
- "value": "`<lr-widget>` — a titled panel shell with an optional collapse toggle and\nan optional fullscreen-expand toggle. Fullscreen promotes the same host\nelement in place (a CSS state, not a clone/portal), so slotted content\n(a chart, a running simulation, scroll position) survives the transition.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The panel body. |\n| `actions` | Header action controls, rendered before the collapse/expand buttons. |\n| `collapse-icon` | Overrides the built-in chevron glyph inside the collapse/expand toggle button entirely, via the platform's own slot-fallback-content mechanism (same convention as `<lr-tool-call-chip>`'s `icon` slot): whatever is assigned wins, otherwise the default chevron renders. Assigned content is decorative, inert, and aria-hidden so the outer toggle remains the sole action. Only meaningful while `collapsible`. |\n| `fullscreen-icon` | Overrides the built-in expand/close glyph inside the fullscreen toggle button entirely, using the same mechanism -- the override replaces *both* the \"expand\" and \"exit fullscreen\" default icons, so a consumer supplying one is responsible for its own expand/exit distinction (e.g. by reading the `fullscreen` attribute). Assigned content is decorative, inert, and aria-hidden so the outer toggle remains the sole action. Only meaningful while `expandable`. |\n| `icon` | Optional decorative leading icon in the title row. Its flattened subtree is inert and hidden from assistive technology. |\n| `label` | Rich label content (overrides the `label` attribute). |\n| `sublabel` | Rich sublabel content (overrides the `sublabel` attribute). |\n| `view-{viewId}` | Content for the view whose `LyraWidgetView.viewId` matches `{viewId}`, rendered when `views` is non-empty. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot. |\n| `backdrop` | The fullscreen scrim behind the panel. |\n| `base` | The panel root (dialog role + backdrop when fullscreen). |\n| `body` | The wrapper around the default slot (the panel body). |\n| `collapse-button` | The collapse/expand toggle button. |\n| `fullscreen-button` | The fullscreen toggle button. |\n| `header` | The header row containing the title, actions, and toggle buttons. |\n| `icon` | Wrapper around the `icon` slot. Hidden entirely when empty. |\n| `label` | The panel title text. |\n| `label-group` | Wrapper around the label and sublabel. |\n| `sublabel` | The panel subtitle text. |\n| `title` | The wrapper around the label/sublabel. |\n| `view-icon` | Decorative icon content inside a view toggle; its subtree is inert and hidden from assistive technology. |\n| `view-label` | Visible label text inside a view toggle. |\n| `view-toggle` | A single view toggle button. |\n| `view-toggles` | The header toggle-button group, only rendered when `views` is non-empty. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroll-fade-size` (default: `2rem`) — Width of the fade at each horizontal scroll edge of the `actions`/`view-toggles` header rows. The fade is applied only while a row actually overflows, so a row that fits is never dimmed. `fullscreen-inset` overrides the safe-area panel inset while the viewport-filling backdrop stays at zero by default. `compact` tightens header/body padding — same convention as `lr-empty`.\n- `--lr-widget-backdrop-inset` (default: `0`) — The `inset` applied to `[part=\"backdrop\"]`, so the scrim can be pulled back independently of the panel. Also set inline from the `backdrop-inset` attribute.\n- `--lr-widget-fullscreen-inset` (default: `max(var(--lr-space-l), var(--lr-safe-area-top)) max(var(--lr-space-l), var(--lr-safe-area-inline-end)) max(var(--lr-space-l), var(--lr-safe-area-bottom)) max(var(--lr-space-l), var(--lr-safe-area-inline-start))`) — The `inset` applied to `[part=\"base\"]` while `fullscreen`. Also set inline from the `fullscreen-inset` attribute.\n- `--lr-widget-overlay-color` (default: `var(--lr-color-overlay)`) — The fullscreen scrim's color, applied to `[part=\"backdrop\"]`.\n- `--lr-widget-view-toggle-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the pressed (`aria-pressed=\"true\"`) view toggle. Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the active toggle without hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-widget-view-toggle-active-border-color` (default: `transparent`) — Border color of the pressed view toggle. Like the active background and text hooks, it is an inline inherited fallback.\n- `--lr-widget-view-toggle-active-color` (default: `var(--lr-color-brand)`) — Text color of the pressed view toggle.\n- `--lr-widget-view-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered `[part=\"view-toggle\"]`.\n- `--lr-widget-view-toggle-hover-color` (default: `var(--lr-color-text)`) — Text color of a hovered `[part=\"view-toggle\"]`."
28132
+ "value": "`<lr-widget>` — a titled panel shell with an optional collapse toggle and\nan optional fullscreen-expand toggle. Fullscreen promotes the same host\nelement in place (a CSS state, not a clone/portal), so slotted content\n(a chart, a running simulation, scroll position) survives the transition.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.0.0`\n- Rationale: This exact lr-* tag appears in a published Lyra release manifest and remains a supported public contract under semver.\n- Graduation: Already stable; it retains that status while its documented behavior, accessibility, compatibility, and cross-browser support remain part of the public contract.\n- Deprecated property `activeView`: Deprecated since `11.2.0`. Use property `activeViewId`. Removal is not permitted before `13.0.0`. `activeView` was this property's original public name; the string does not appear anywhere in CHANGELOG.md, so the rename to `activeViewId` was never announced at all. A shipped consumer's `.activeView=` binding became a dead expando and the widget fell back to its first view with no error. The alias seeds `activeViewId` rather than being read alongside it, because the component itself writes that property (a view-toggle click, and the fallback when `views` drops the active id), and a read-alongside alias would undo a later interactive change on the next update.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The panel body. |\n| `actions` | Header action controls, rendered before the collapse/expand buttons. |\n| `collapse-icon` | Overrides the built-in chevron glyph inside the collapse/expand toggle button entirely, via the platform's own slot-fallback-content mechanism (same convention as `<lr-tool-call-chip>`'s `icon` slot): whatever is assigned wins, otherwise the default chevron renders. Assigned content is decorative, inert, and aria-hidden so the outer toggle remains the sole action. Only meaningful while `collapsible`. |\n| `fullscreen-icon` | Overrides the built-in expand/close glyph inside the fullscreen toggle button entirely, using the same mechanism -- the override replaces *both* the \"expand\" and \"exit fullscreen\" default icons, so a consumer supplying one is responsible for its own expand/exit distinction (e.g. by reading the `fullscreen` attribute). Assigned content is decorative, inert, and aria-hidden so the outer toggle remains the sole action. Only meaningful while `expandable`. |\n| `icon` | Optional decorative leading icon in the title row. Its flattened subtree is inert and hidden from assistive technology. |\n| `label` | Rich label content (overrides the `label` attribute). |\n| `sublabel` | Rich sublabel content (overrides the `sublabel` attribute). |\n| `view-{viewId}` | Content for the view whose `LyraWidgetView.viewId` matches `{viewId}`, rendered when `views` is non-empty. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot. |\n| `backdrop` | The fullscreen scrim behind the panel. |\n| `base` | The panel root (dialog role + backdrop when fullscreen). |\n| `body` | The wrapper around the default slot (the panel body). |\n| `collapse-button` | The collapse/expand toggle button. |\n| `fullscreen-button` | The fullscreen toggle button. |\n| `header` | The header row containing the title, actions, and toggle buttons. |\n| `icon` | Wrapper around the `icon` slot. Hidden entirely when empty. |\n| `label` | The panel title text. |\n| `label-group` | Wrapper around the label and sublabel. |\n| `sublabel` | The panel subtitle text. |\n| `title` | The wrapper around the label/sublabel. |\n| `view-icon` | Decorative icon content inside a view toggle; its subtree is inert and hidden from assistive technology. |\n| `view-label` | Visible label text inside a view toggle. |\n| `view-toggle` | A single view toggle button. |\n| `view-toggles` | The header toggle-button group, only rendered when `views` is non-empty. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroll-fade-size` (default: `2rem`) — Width of the fade at each horizontal scroll edge of the `actions`/`view-toggles` header rows. The fade is applied only while a row actually overflows, so a row that fits is never dimmed. `fullscreen-inset` overrides the safe-area panel inset while the viewport-filling backdrop stays at zero by default. `compact` tightens header/body padding — same convention as `lr-empty`.\n- `--lr-widget-backdrop-inset` (default: `0`) — The `inset` applied to `[part=\"backdrop\"]`, so the scrim can be pulled back independently of the panel. Also set inline from the `backdrop-inset` attribute.\n- `--lr-widget-fullscreen-inset` (default: `max(var(--lr-space-l), var(--lr-safe-area-top)) max(var(--lr-space-l), var(--lr-safe-area-inline-end)) max(var(--lr-space-l), var(--lr-safe-area-bottom)) max(var(--lr-space-l), var(--lr-safe-area-inline-start))`) — The `inset` applied to `[part=\"base\"]` while `fullscreen`. Also set inline from the `fullscreen-inset` attribute.\n- `--lr-widget-overlay-color` (default: `var(--lr-color-overlay)`) — The fullscreen scrim's color, applied to `[part=\"backdrop\"]`.\n- `--lr-widget-view-toggle-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the pressed (`aria-pressed=\"true\"`) view toggle. Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the active toggle without hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-widget-view-toggle-active-border-color` (default: `transparent`) — Border color of the pressed view toggle. Like the active background and text hooks, it is an inline inherited fallback.\n- `--lr-widget-view-toggle-active-color` (default: `var(--lr-color-brand)`) — Text color of the pressed view toggle.\n- `--lr-widget-view-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered `[part=\"view-toggle\"]`.\n- `--lr-widget-view-toggle-hover-color` (default: `var(--lr-color-text)`) — Text color of a hovered `[part=\"view-toggle\"]`."
28048
28133
  },
28049
28134
  "attributes": [
28050
28135
  {